revert mapstructure to the commit listed in master
This commit is contained in:
parent
cfa299d2ee
commit
0ca492691a
|
@ -72,10 +72,7 @@ func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modify the from kind to be correct with the new data
|
// Modify the from kind to be correct with the new data
|
||||||
f = nil
|
f = reflect.ValueOf(data).Type()
|
||||||
if val := reflect.ValueOf(data); val.IsValid() {
|
|
||||||
f = val.Type()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data, nil
|
return data, nil
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// The mapstructure package exposes functionality to convert an
|
// The mapstructure package exposes functionality to convert an
|
||||||
// arbitrary map[string]interface{} into a native Go structure.
|
// abitrary map[string]interface{} into a native Go structure.
|
||||||
//
|
//
|
||||||
// The Go structure can be arbitrarily complex, containing slices,
|
// The Go structure can be arbitrarily complex, containing slices,
|
||||||
// other structs, etc. and the decoder will properly decode nested
|
// other structs, etc. and the decoder will properly decode nested
|
||||||
|
@ -8,7 +8,6 @@
|
||||||
package mapstructure
|
package mapstructure
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -68,7 +67,6 @@ type DecoderConfig struct {
|
||||||
// FALSE, false, False. Anything else is an error)
|
// FALSE, false, False. Anything else is an error)
|
||||||
// - empty array = empty map and vice versa
|
// - empty array = empty map and vice versa
|
||||||
// - negative numbers to overflowed uint values (base 10)
|
// - negative numbers to overflowed uint values (base 10)
|
||||||
// - slice of maps to a merged map
|
|
||||||
//
|
//
|
||||||
WeaklyTypedInput bool
|
WeaklyTypedInput bool
|
||||||
|
|
||||||
|
@ -202,7 +200,7 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error
|
||||||
d.config.DecodeHook,
|
d.config.DecodeHook,
|
||||||
dataVal.Type(), val.Type(), data)
|
dataVal.Type(), val.Type(), data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error decoding '%s': %s", name, err)
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,8 +227,6 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error
|
||||||
err = d.decodePtr(name, data, val)
|
err = d.decodePtr(name, data, val)
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
err = d.decodeSlice(name, data, val)
|
err = d.decodeSlice(name, data, val)
|
||||||
case reflect.Func:
|
|
||||||
err = d.decodeFunc(name, data, val)
|
|
||||||
default:
|
default:
|
||||||
// If we reached this point then we weren't able to decode it
|
// If we reached this point then we weren't able to decode it
|
||||||
return fmt.Errorf("%s: unsupported type: %s", name, dataKind)
|
return fmt.Errorf("%s: unsupported type: %s", name, dataKind)
|
||||||
|
@ -249,10 +245,6 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error
|
||||||
// value to "data" of that type.
|
// value to "data" of that type.
|
||||||
func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
|
||||||
dataVal := reflect.ValueOf(data)
|
dataVal := reflect.ValueOf(data)
|
||||||
if !dataVal.IsValid() {
|
|
||||||
dataVal = reflect.Zero(val.Type())
|
|
||||||
}
|
|
||||||
|
|
||||||
dataValType := dataVal.Type()
|
dataValType := dataVal.Type()
|
||||||
if !dataValType.AssignableTo(val.Type()) {
|
if !dataValType.AssignableTo(val.Type()) {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
|
@ -309,7 +301,6 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value)
|
||||||
func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
|
||||||
dataVal := reflect.ValueOf(data)
|
dataVal := reflect.ValueOf(data)
|
||||||
dataKind := getKind(dataVal)
|
dataKind := getKind(dataVal)
|
||||||
dataType := dataVal.Type()
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case dataKind == reflect.Int:
|
case dataKind == reflect.Int:
|
||||||
|
@ -331,14 +322,6 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
|
return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
|
||||||
}
|
}
|
||||||
case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
|
|
||||||
jn := data.(json.Number)
|
|
||||||
i, err := jn.Int64()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"error decoding json.Number into %s: %s", name, err)
|
|
||||||
}
|
|
||||||
val.SetInt(i)
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
"'%s' expected type '%s', got unconvertible type '%s'",
|
||||||
|
@ -425,7 +408,6 @@ func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) e
|
||||||
func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
|
||||||
dataVal := reflect.ValueOf(data)
|
dataVal := reflect.ValueOf(data)
|
||||||
dataKind := getKind(dataVal)
|
dataKind := getKind(dataVal)
|
||||||
dataType := dataVal.Type()
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case dataKind == reflect.Int:
|
case dataKind == reflect.Int:
|
||||||
|
@ -447,14 +429,6 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("cannot parse '%s' as float: %s", name, err)
|
return fmt.Errorf("cannot parse '%s' as float: %s", name, err)
|
||||||
}
|
}
|
||||||
case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
|
|
||||||
jn := data.(json.Number)
|
|
||||||
i, err := jn.Float64()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"error decoding json.Number into %s: %s", name, err)
|
|
||||||
}
|
|
||||||
val.SetFloat(i)
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
"'%s' expected type '%s', got unconvertible type '%s'",
|
||||||
|
@ -482,31 +456,16 @@ func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) er
|
||||||
// Check input type
|
// Check input type
|
||||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||||
if dataVal.Kind() != reflect.Map {
|
if dataVal.Kind() != reflect.Map {
|
||||||
// In weak mode, we accept a slice of maps as an input...
|
// Accept empty array/slice instead of an empty map in weakly typed mode
|
||||||
if d.config.WeaklyTypedInput {
|
if d.config.WeaklyTypedInput &&
|
||||||
switch dataVal.Kind() {
|
(dataVal.Kind() == reflect.Slice || dataVal.Kind() == reflect.Array) &&
|
||||||
case reflect.Array, reflect.Slice:
|
dataVal.Len() == 0 {
|
||||||
// Special case for BC reasons (covered by tests)
|
|
||||||
if dataVal.Len() == 0 {
|
|
||||||
val.Set(valMap)
|
val.Set(valMap)
|
||||||
return nil
|
return nil
|
||||||
}
|
} else {
|
||||||
|
|
||||||
for i := 0; i < dataVal.Len(); i++ {
|
|
||||||
err := d.decode(
|
|
||||||
fmt.Sprintf("%s[%d]", name, i),
|
|
||||||
dataVal.Index(i).Interface(), val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
|
return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Accumulate errors
|
// Accumulate errors
|
||||||
errors := make([]string, 0)
|
errors := make([]string, 0)
|
||||||
|
@ -548,12 +507,7 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) er
|
||||||
// into that. Then set the value of the pointer to this type.
|
// into that. Then set the value of the pointer to this type.
|
||||||
valType := val.Type()
|
valType := val.Type()
|
||||||
valElemType := valType.Elem()
|
valElemType := valType.Elem()
|
||||||
|
realVal := reflect.New(valElemType)
|
||||||
realVal := val
|
|
||||||
if realVal.IsNil() || d.config.ZeroFields {
|
|
||||||
realVal = reflect.New(valElemType)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
|
if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -562,19 +516,6 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) er
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
|
|
||||||
// Create an element of the concrete (non pointer) type and decode
|
|
||||||
// into that. Then set the value of the pointer to this type.
|
|
||||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
|
||||||
if val.Type() != dataVal.Type() {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
|
||||||
name, val.Type(), dataVal.Type())
|
|
||||||
}
|
|
||||||
val.Set(dataVal)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
|
func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
|
||||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||||
dataValKind := dataVal.Kind()
|
dataValKind := dataVal.Kind()
|
||||||
|
@ -582,9 +523,6 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||||
valElemType := valType.Elem()
|
valElemType := valType.Elem()
|
||||||
sliceType := reflect.SliceOf(valElemType)
|
sliceType := reflect.SliceOf(valElemType)
|
||||||
|
|
||||||
valSlice := val
|
|
||||||
if valSlice.IsNil() || d.config.ZeroFields {
|
|
||||||
|
|
||||||
// Check input type
|
// Check input type
|
||||||
if dataValKind != reflect.Array && dataValKind != reflect.Slice {
|
if dataValKind != reflect.Array && dataValKind != reflect.Slice {
|
||||||
// Accept empty map instead of array/slice in weakly typed mode
|
// Accept empty map instead of array/slice in weakly typed mode
|
||||||
|
@ -598,8 +536,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a new slice to hold our result, same size as the original data.
|
// Make a new slice to hold our result, same size as the original data.
|
||||||
valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
|
valSlice := reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
|
||||||
}
|
|
||||||
|
|
||||||
// Accumulate any errors
|
// Accumulate any errors
|
||||||
errors := make([]string, 0)
|
errors := make([]string, 0)
|
||||||
|
@ -670,10 +607,17 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
|
||||||
structs = structs[1:]
|
structs = structs[1:]
|
||||||
|
|
||||||
structType := structVal.Type()
|
structType := structVal.Type()
|
||||||
|
|
||||||
for i := 0; i < structType.NumField(); i++ {
|
for i := 0; i < structType.NumField(); i++ {
|
||||||
fieldType := structType.Field(i)
|
fieldType := structType.Field(i)
|
||||||
|
|
||||||
|
if fieldType.Anonymous {
|
||||||
fieldKind := fieldType.Type.Kind()
|
fieldKind := fieldType.Type.Kind()
|
||||||
|
if fieldKind != reflect.Struct {
|
||||||
|
errors = appendErrors(errors,
|
||||||
|
fmt.Errorf("%s: unsupported type: %s", fieldType.Name, fieldKind))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If "squash" is specified in the tag, we squash the field down.
|
// If "squash" is specified in the tag, we squash the field down.
|
||||||
squash := false
|
squash := false
|
||||||
|
@ -686,12 +630,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if squash {
|
if squash {
|
||||||
if fieldKind != reflect.Struct {
|
|
||||||
errors = appendErrors(errors,
|
|
||||||
fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind))
|
|
||||||
} else {
|
|
||||||
structs = append(structs, val.FieldByName(fieldType.Name))
|
structs = append(structs, val.FieldByName(fieldType.Name))
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,7 +653,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
|
||||||
if !rawMapVal.IsValid() {
|
if !rawMapVal.IsValid() {
|
||||||
// Do a slower search by iterating over each key and
|
// Do a slower search by iterating over each key and
|
||||||
// doing case-insensitive search.
|
// doing case-insensitive search.
|
||||||
for dataValKey := range dataValKeys {
|
for dataValKey, _ := range dataValKeys {
|
||||||
mK, ok := dataValKey.Interface().(string)
|
mK, ok := dataValKey.Interface().(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
// Not a string key
|
// Not a string key
|
||||||
|
@ -762,7 +701,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
|
||||||
|
|
||||||
if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
|
if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
|
||||||
keys := make([]string, 0, len(dataValKeysUnused))
|
keys := make([]string, 0, len(dataValKeysUnused))
|
||||||
for rawKey := range dataValKeysUnused {
|
for rawKey, _ := range dataValKeysUnused {
|
||||||
keys = append(keys, rawKey.(string))
|
keys = append(keys, rawKey.(string))
|
||||||
}
|
}
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
|
@ -777,7 +716,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
|
||||||
|
|
||||||
// Add the unused keys to the list of unused keys if we're tracking metadata
|
// Add the unused keys to the list of unused keys if we're tracking metadata
|
||||||
if d.config.Metadata != nil {
|
if d.config.Metadata != nil {
|
||||||
for rawKey := range dataValKeysUnused {
|
for rawKey, _ := range dataValKeysUnused {
|
||||||
key := rawKey.(string)
|
key := rawKey.(string)
|
||||||
if name != "" {
|
if name != "" {
|
||||||
key = fmt.Sprintf("%s.%s", name, key)
|
key = fmt.Sprintf("%s.%s", name, key)
|
||||||
|
|
|
@ -2211,10 +2211,9 @@
|
||||||
"revision": "6b17d669fac5e2f71c16658d781ec3fdd3802b69"
|
"revision": "6b17d669fac5e2f71c16658d781ec3fdd3802b69"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "0lYe+0oPjhUOecK2xxOsDJuxbK4=",
|
"checksumSHA1": "4Js6Jlu93Wa0o6Kjt393L9Z7diE=",
|
||||||
"path": "github.com/mitchellh/mapstructure",
|
"path": "github.com/mitchellh/mapstructure",
|
||||||
"revision": "ed105d635dfa9ea7133f7c79f1eb36203fc3a156",
|
"revision": "281073eb9eb092240d33ef253c404f1cca550309"
|
||||||
"revisionTime": "2017-01-18T00:13:03Z"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "e/MV3GL8ZOpqyNSKVPtMeqTRR/w=",
|
"checksumSHA1": "e/MV3GL8ZOpqyNSKVPtMeqTRR/w=",
|
||||||
|
|
Loading…
Reference in New Issue