diff options
Diffstat (limited to 'vendor/github.com/pelletier/go-toml/v2/unmarshaler.go')
-rw-r--r-- | vendor/github.com/pelletier/go-toml/v2/unmarshaler.go | 75 |
1 files changed, 54 insertions, 21 deletions
diff --git a/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go b/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go index 70f6ec57..39350343 100644 --- a/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go +++ b/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go @@ -60,7 +60,7 @@ func (d *Decoder) DisallowUnknownFields() *Decoder { // are ignored. See Decoder.DisallowUnknownFields() to change this behavior. // // When a TOML local date, time, or date-time is decoded into a time.Time, its -// value is represented in time.Local timezone. Otherwise the approriate Local* +// value is represented in time.Local timezone. Otherwise the appropriate Local* // structure is used. For time values, precision up to the nanosecond is // supported by truncating extra digits. // @@ -417,7 +417,10 @@ func (d *decoder) handleKeyPart(key unstable.Iterator, v reflect.Value, nextFn h vt := v.Type() // Create the key for the map element. Convert to key type. - mk := reflect.ValueOf(string(key.Node().Data)).Convert(vt.Key()) + mk, err := d.keyFromData(vt.Key(), key.Node().Data) + if err != nil { + return reflect.Value{}, err + } // If the map does not exist, create it. if v.IsNil() { @@ -746,7 +749,7 @@ func (d *decoder) unmarshalInlineTable(itable *unstable.Node, v reflect.Value) e } return d.unmarshalInlineTable(itable, elem) default: - return unstable.NewParserError(itable.Data, "cannot store inline table in Go type %s", v.Kind()) + return unstable.NewParserError(d.p.Raw(itable.Raw), "cannot store inline table in Go type %s", v.Kind()) } it := itable.Children() @@ -887,6 +890,11 @@ func init() { } func (d *decoder) unmarshalInteger(value *unstable.Node, v reflect.Value) error { + kind := v.Kind() + if kind == reflect.Float32 || kind == reflect.Float64 { + return d.unmarshalFloat(value, v) + } + i, err := parseInteger(value.Data) if err != nil { return err @@ -894,7 +902,7 @@ func (d *decoder) unmarshalInteger(value *unstable.Node, v reflect.Value) error var r reflect.Value - switch v.Kind() { + switch kind { case reflect.Int64: v.SetInt(i) return nil @@ -1004,6 +1012,31 @@ func (d *decoder) handleKeyValueInner(key unstable.Iterator, value *unstable.Nod return reflect.Value{}, d.handleValue(value, v) } +func (d *decoder) keyFromData(keyType reflect.Type, data []byte) (reflect.Value, error) { + switch { + case stringType.AssignableTo(keyType): + return reflect.ValueOf(string(data)), nil + + case stringType.ConvertibleTo(keyType): + return reflect.ValueOf(string(data)).Convert(keyType), nil + + case keyType.Implements(textUnmarshalerType): + mk := reflect.New(keyType.Elem()) + if err := mk.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil { + return reflect.Value{}, fmt.Errorf("toml: error unmarshalling key type %s from text: %w", stringType, err) + } + return mk, nil + + case reflect.PtrTo(keyType).Implements(textUnmarshalerType): + mk := reflect.New(keyType) + if err := mk.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil { + return reflect.Value{}, fmt.Errorf("toml: error unmarshalling key type %s from text: %w", stringType, err) + } + return mk.Elem(), nil + } + return reflect.Value{}, fmt.Errorf("toml: cannot convert map key of type %s to expected type %s", stringType, keyType) +} + func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node, v reflect.Value) (reflect.Value, error) { // contains the replacement for v var rv reflect.Value @@ -1014,16 +1047,9 @@ func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node case reflect.Map: vt := v.Type() - mk := reflect.ValueOf(string(key.Node().Data)) - mkt := stringType - - keyType := vt.Key() - if !mkt.AssignableTo(keyType) { - if !mkt.ConvertibleTo(keyType) { - return reflect.Value{}, fmt.Errorf("toml: cannot convert map key of type %s to expected type %s", mkt, keyType) - } - - mk = mk.Convert(keyType) + mk, err := d.keyFromData(vt.Key(), key.Node().Data) + if err != nil { + return reflect.Value{}, err } // If the map does not exist, create it. @@ -1034,15 +1060,9 @@ func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node mv := v.MapIndex(mk) set := false - if !mv.IsValid() { + if !mv.IsValid() || key.IsLast() { set = true mv = reflect.New(v.Type().Elem()).Elem() - } else { - if key.IsLast() { - var x interface{} - mv = reflect.ValueOf(&x).Elem() - set = true - } } nv, err := d.handleKeyValueInner(key, value, mv) @@ -1072,6 +1092,19 @@ func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node d.errorContext.Field = path f := fieldByIndex(v, path) + + if !f.CanSet() { + // If the field is not settable, need to take a slower path and make a copy of + // the struct itself to a new location. + nvp := reflect.New(v.Type()) + nvp.Elem().Set(v) + v = nvp.Elem() + _, err := d.handleKeyValuePart(key, value, v) + if err != nil { + return reflect.Value{}, err + } + return nvp.Elem(), nil + } x, err := d.handleKeyValueInner(key, value, f) if err != nil { return reflect.Value{}, err |