Updates mitchellh/copystructure, mitchellh/mapstructure, and mitchellh/reflectwalk.
This commit is contained in:
parent
33ea18fb21
commit
ce206323bb
|
@ -95,7 +95,9 @@ func (w *walker) Exit(l reflectwalk.Location) error {
|
||||||
if v.IsValid() {
|
if v.IsValid() {
|
||||||
s := w.cs[len(w.cs)-1]
|
s := w.cs[len(w.cs)-1]
|
||||||
sf := reflect.Indirect(s).FieldByName(f.Name)
|
sf := reflect.Indirect(s).FieldByName(f.Name)
|
||||||
sf.Set(v)
|
if sf.CanSet() {
|
||||||
|
sf.Set(v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case reflectwalk.WalkLoc:
|
case reflectwalk.WalkLoc:
|
||||||
// Clear out the slices for GC
|
// Clear out the slices for GC
|
||||||
|
@ -111,16 +113,12 @@ func (w *walker) Map(m reflect.Value) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the type for the map
|
|
||||||
t := m.Type()
|
|
||||||
mapType := reflect.MapOf(t.Key(), t.Elem())
|
|
||||||
|
|
||||||
// Create the map. If the map itself is nil, then just make a nil map
|
// Create the map. If the map itself is nil, then just make a nil map
|
||||||
var newMap reflect.Value
|
var newMap reflect.Value
|
||||||
if m.IsNil() {
|
if m.IsNil() {
|
||||||
newMap = reflect.Indirect(reflect.New(mapType))
|
newMap = reflect.Indirect(reflect.New(m.Type()))
|
||||||
} else {
|
} else {
|
||||||
newMap = reflect.MakeMap(reflect.MapOf(t.Key(), t.Elem()))
|
newMap = reflect.MakeMap(m.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
w.cs = append(w.cs, newMap)
|
w.cs = append(w.cs, newMap)
|
||||||
|
@ -155,8 +153,10 @@ func (w *walker) Primitive(v reflect.Value) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsValid verifies the v is non-zero and CanInterface verifies
|
||||||
|
// that we're allowed to read this value (unexported fields).
|
||||||
var newV reflect.Value
|
var newV reflect.Value
|
||||||
if v.IsValid() {
|
if v.IsValid() && v.CanInterface() {
|
||||||
newV = reflect.New(v.Type())
|
newV = reflect.New(v.Type())
|
||||||
reflect.Indirect(newV).Set(v)
|
reflect.Indirect(newV).Set(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.4
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go test
|
|
|
@ -72,7 +72,10 @@ 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 = reflect.ValueOf(data).Type()
|
f = nil
|
||||||
|
if val := reflect.ValueOf(data); val.IsValid() {
|
||||||
|
f = val.Type()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return data, nil
|
return data, nil
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
package mapstructure
|
package mapstructure
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -67,6 +68,7 @@ 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
|
||||||
|
|
||||||
|
@ -245,6 +247,10 @@ 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(
|
||||||
|
@ -301,6 +307,7 @@ 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:
|
||||||
|
@ -322,6 +329,14 @@ 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'",
|
||||||
|
@ -408,6 +423,7 @@ 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:
|
||||||
|
@ -429,6 +445,14 @@ 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'",
|
||||||
|
@ -456,15 +480,30 @@ 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 {
|
||||||
// Accept empty array/slice instead of an empty map in weakly typed mode
|
// In weak mode, we accept a slice of maps as an input...
|
||||||
if d.config.WeaklyTypedInput &&
|
if d.config.WeaklyTypedInput {
|
||||||
(dataVal.Kind() == reflect.Slice || dataVal.Kind() == reflect.Array) &&
|
switch dataVal.Kind() {
|
||||||
dataVal.Len() == 0 {
|
case reflect.Array, reflect.Slice:
|
||||||
val.Set(valMap)
|
// Special case for BC reasons (covered by tests)
|
||||||
return nil
|
if dataVal.Len() == 0 {
|
||||||
} else {
|
val.Set(valMap)
|
||||||
return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accumulate errors
|
// Accumulate errors
|
||||||
|
@ -607,11 +646,12 @@ 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)
|
||||||
|
fieldKind := fieldType.Type.Kind()
|
||||||
|
|
||||||
if fieldType.Anonymous {
|
if fieldType.Anonymous {
|
||||||
fieldKind := fieldType.Type.Kind()
|
|
||||||
if fieldKind != reflect.Struct {
|
if fieldKind != reflect.Struct {
|
||||||
errors = appendErrors(errors,
|
errors = appendErrors(errors,
|
||||||
fmt.Errorf("%s: unsupported type: %s", fieldType.Name, fieldKind))
|
fmt.Errorf("%s: unsupported type: %s", fieldType.Name, fieldKind))
|
||||||
|
@ -630,7 +670,12 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if squash {
|
if squash {
|
||||||
structs = append(structs, val.FieldByName(fieldType.Name))
|
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))
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -438,16 +438,22 @@
|
||||||
"revisionTime": "2016-03-23T17:07:00Z"
|
"revisionTime": "2016-03-23T17:07:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"checksumSHA1": "86nE93o1VIND0Doe8PuhCXnhUx0=",
|
||||||
"path": "github.com/mitchellh/copystructure",
|
"path": "github.com/mitchellh/copystructure",
|
||||||
"revision": "6fc66267e9da7d155a9d3bd489e00dad02666dc6"
|
"revision": "cdac8253d00f2ecf0a0b19fbff173a9a72de4f82",
|
||||||
|
"revisionTime": "2016-08-04T03:23:30Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"checksumSHA1": "LUrnGREfnifW4WDMaavmc9MlLI0=",
|
||||||
"path": "github.com/mitchellh/mapstructure",
|
"path": "github.com/mitchellh/mapstructure",
|
||||||
"revision": "281073eb9eb092240d33ef253c404f1cca550309"
|
"revision": "ca63d7c062ee3c9f34db231e352b60012b4fd0c1",
|
||||||
|
"revisionTime": "2016-08-08T18:12:53Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"checksumSHA1": "mrqMlK6gqe//WsJSrJ1HgkPM0lM=",
|
||||||
"path": "github.com/mitchellh/reflectwalk",
|
"path": "github.com/mitchellh/reflectwalk",
|
||||||
"revision": "eecf4c70c626c7cfbb95c90195bc34d386c74ac6"
|
"revision": "eecf4c70c626c7cfbb95c90195bc34d386c74ac6",
|
||||||
|
"revisionTime": "2015-05-27T15:31:53Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "3AoPMXlmVq2+iWMpsdJZkcUKHB8=",
|
"checksumSHA1": "3AoPMXlmVq2+iWMpsdJZkcUKHB8=",
|
||||||
|
|
Loading…
Reference in New Issue