diff options
| author | Gibheer <gibheer+git@zero-knowledge.org> | 2024-09-05 19:38:25 +0200 | 
|---|---|---|
| committer | Gibheer <gibheer+git@zero-knowledge.org> | 2024-09-05 19:38:25 +0200 | 
| commit | 6ea4d2c82de80efc87708e5e182034b7c6c2019e (patch) | |
| tree | 35c0856a929040216c82153ca62d43b27530a887 /vendor/github.com/BurntSushi/toml/encode.go | |
| parent | 6f64eeace1b66639b9380b44e88a8d54850a4306 (diff) | |
lib/pq is out of maintenance for some time now, so switch to the newer
more active library. Looks like it finally stabilized after a long time.
Diffstat (limited to 'vendor/github.com/BurntSushi/toml/encode.go')
| -rw-r--r-- | vendor/github.com/BurntSushi/toml/encode.go | 98 | 
1 files changed, 63 insertions, 35 deletions
diff --git a/vendor/github.com/BurntSushi/toml/encode.go b/vendor/github.com/BurntSushi/toml/encode.go index 930e1d5..73366c0 100644 --- a/vendor/github.com/BurntSushi/toml/encode.go +++ b/vendor/github.com/BurntSushi/toml/encode.go @@ -2,6 +2,7 @@ package toml  import (  	"bufio" +	"bytes"  	"encoding"  	"encoding/json"  	"errors" @@ -76,6 +77,17 @@ type Marshaler interface {  	MarshalTOML() ([]byte, error)  } +// Marshal returns a TOML representation of the Go value. +// +// See [Encoder] for a description of the encoding process. +func Marshal(v any) ([]byte, error) { +	buff := new(bytes.Buffer) +	if err := NewEncoder(buff).Encode(v); err != nil { +		return nil, err +	} +	return buff.Bytes(), nil +} +  // Encoder encodes a Go to a TOML document.  //  // The mapping between Go values and TOML values should be precisely the same as @@ -115,28 +127,24 @@ type Marshaler interface {  // NOTE: only exported keys are encoded due to the use of reflection. Unexported  // keys are silently discarded.  type Encoder struct { -	// String to use for a single indentation level; default is two spaces. -	Indent string - +	Indent     string // string for a single indentation level; default is two spaces. +	hasWritten bool   // written any output to w yet?  	w          *bufio.Writer -	hasWritten bool // written any output to w yet?  }  // NewEncoder create a new Encoder.  func NewEncoder(w io.Writer) *Encoder { -	return &Encoder{ -		w:      bufio.NewWriter(w), -		Indent: "  ", -	} +	return &Encoder{w: bufio.NewWriter(w), Indent: "  "}  }  // Encode writes a TOML representation of the Go value to the [Encoder]'s writer.  //  // An error is returned if the value given cannot be encoded to a valid TOML  // document. -func (enc *Encoder) Encode(v interface{}) error { +func (enc *Encoder) Encode(v any) error {  	rv := eindirect(reflect.ValueOf(v)) -	if err := enc.safeEncode(Key([]string{}), rv); err != nil { +	err := enc.safeEncode(Key([]string{}), rv) +	if err != nil {  		return err  	}  	return enc.w.Flush() @@ -279,18 +287,30 @@ func (enc *Encoder) eElement(rv reflect.Value) {  	case reflect.Float32:  		f := rv.Float()  		if math.IsNaN(f) { +			if math.Signbit(f) { +				enc.wf("-") +			}  			enc.wf("nan")  		} else if math.IsInf(f, 0) { -			enc.wf("%cinf", map[bool]byte{true: '-', false: '+'}[math.Signbit(f)]) +			if math.Signbit(f) { +				enc.wf("-") +			} +			enc.wf("inf")  		} else {  			enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 32)))  		}  	case reflect.Float64:  		f := rv.Float()  		if math.IsNaN(f) { +			if math.Signbit(f) { +				enc.wf("-") +			}  			enc.wf("nan")  		} else if math.IsInf(f, 0) { -			enc.wf("%cinf", map[bool]byte{true: '-', false: '+'}[math.Signbit(f)]) +			if math.Signbit(f) { +				enc.wf("-") +			} +			enc.wf("inf")  		} else {  			enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 64)))  		} @@ -303,7 +323,7 @@ func (enc *Encoder) eElement(rv reflect.Value) {  	case reflect.Interface:  		enc.eElement(rv.Elem())  	default: -		encPanic(fmt.Errorf("unexpected type: %T", rv.Interface())) +		encPanic(fmt.Errorf("unexpected type: %s", fmtType(rv.Interface())))  	}  } @@ -457,6 +477,16 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {  			frv := eindirect(rv.Field(i)) +			if is32Bit { +				// Copy so it works correct on 32bit archs; not clear why this +				// is needed. See #314, and https://www.reddit.com/r/golang/comments/pnx8v4 +				// This also works fine on 64bit, but 32bit archs are somewhat +				// rare and this is a wee bit faster. +				copyStart := make([]int, len(start)) +				copy(copyStart, start) +				start = copyStart +			} +  			// Treat anonymous struct fields with tag names as though they are  			// not anonymous, like encoding/json does.  			// @@ -471,17 +501,7 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {  			if typeIsTable(tomlTypeOfGo(frv)) {  				fieldsSub = append(fieldsSub, append(start, f.Index...))  			} else { -				// Copy so it works correct on 32bit archs; not clear why this -				// is needed. See #314, and https://www.reddit.com/r/golang/comments/pnx8v4 -				// This also works fine on 64bit, but 32bit archs are somewhat -				// rare and this is a wee bit faster. -				if is32Bit { -					copyStart := make([]int, len(start)) -					copy(copyStart, start) -					fieldsDirect = append(fieldsDirect, append(copyStart, f.Index...)) -				} else { -					fieldsDirect = append(fieldsDirect, append(start, f.Index...)) -				} +				fieldsDirect = append(fieldsDirect, append(start, f.Index...))  			}  		}  	} @@ -490,24 +510,27 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {  	writeFields := func(fields [][]int) {  		for _, fieldIndex := range fields {  			fieldType := rt.FieldByIndex(fieldIndex) -			fieldVal := eindirect(rv.FieldByIndex(fieldIndex)) +			fieldVal := rv.FieldByIndex(fieldIndex) -			if isNil(fieldVal) { /// Don't write anything for nil fields. +			opts := getOptions(fieldType.Tag) +			if opts.skip { +				continue +			} +			if opts.omitempty && isEmpty(fieldVal) {  				continue  			} -			opts := getOptions(fieldType.Tag) -			if opts.skip { +			fieldVal = eindirect(fieldVal) + +			if isNil(fieldVal) { /// Don't write anything for nil fields.  				continue  			} +  			keyName := fieldType.Name  			if opts.name != "" {  				keyName = opts.name  			} -			if opts.omitempty && enc.isEmpty(fieldVal) { -				continue -			}  			if opts.omitzero && isZero(fieldVal) {  				continue  			} @@ -649,7 +672,7 @@ func isZero(rv reflect.Value) bool {  	return false  } -func (enc *Encoder) isEmpty(rv reflect.Value) bool { +func isEmpty(rv reflect.Value) bool {  	switch rv.Kind() {  	case reflect.Array, reflect.Slice, reflect.Map, reflect.String:  		return rv.Len() == 0 @@ -664,13 +687,15 @@ func (enc *Encoder) isEmpty(rv reflect.Value) bool {  		//   type b struct{ s []string }  		//   s := a{field: b{s: []string{"AAA"}}}  		for i := 0; i < rv.NumField(); i++ { -			if !enc.isEmpty(rv.Field(i)) { +			if !isEmpty(rv.Field(i)) {  				return false  			}  		}  		return true  	case reflect.Bool:  		return !rv.Bool() +	case reflect.Ptr: +		return rv.IsNil()  	}  	return false  } @@ -693,8 +718,11 @@ func (enc *Encoder) newline() {  //	v      v   v  v    vv  //	key = {k = 1, k2 = 2}  func (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) { +	/// Marshaler used on top-level document; call eElement() to just call +	/// Marshal{TOML,Text}.  	if len(key) == 0 { -		encPanic(errNoKey) +		enc.eElement(val) +		return  	}  	enc.wf("%s%s = ", enc.indentStr(key), key.maybeQuoted(len(key)-1))  	enc.eElement(val) @@ -703,7 +731,7 @@ func (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) {  	}  } -func (enc *Encoder) wf(format string, v ...interface{}) { +func (enc *Encoder) wf(format string, v ...any) {  	_, err := fmt.Fprintf(enc.w, format, v...)  	if err != nil {  		encPanic(err)  | 
