structs: fix interface{} type with map values

Fixes #76
This commit is contained in:
Fatih Arslan 2016-08-07 19:55:29 -04:00
parent bf7dff7189
commit 1fe66a405b
2 changed files with 38 additions and 5 deletions

View File

@ -530,15 +530,22 @@ func (s *Struct) nested(val reflect.Value) interface{} {
finalVal = m
}
case reflect.Map:
v := val.Type().Elem()
if v.Kind() == reflect.Ptr {
v = v.Elem()
// get the element type of the map
mapElem := val.Type()
switch val.Type().Kind() {
case reflect.Ptr, reflect.Array, reflect.Map,
reflect.Slice, reflect.Chan:
mapElem = val.Type().Elem()
if mapElem.Kind() == reflect.Ptr {
mapElem = mapElem.Elem()
}
}
// only iterate over struct types, ie: map[string]StructType,
// map[string][]StructType,
if v.Kind() == reflect.Struct ||
(v.Kind() == reflect.Slice && v.Elem().Kind() == reflect.Struct) {
if mapElem.Kind() == reflect.Struct ||
(mapElem.Kind() == reflect.Slice &&
mapElem.Elem().Kind() == reflect.Struct) {
m := make(map[string]interface{}, val.Len())
for _, k := range val.MapKeys() {
m[k.String()] = s.nested(val.MapIndex(k))
@ -558,6 +565,7 @@ func (s *Struct) nested(val reflect.Value) interface{} {
// TODO(arslan): should this be optional?
// do not iterate of non struct types, just pass the value. Ie: []int,
// []string, co... We only iterate further if it's a struct.
// i.e []foo or []*foo
if val.Type().Elem().Kind() != reflect.Struct &&
!(val.Type().Elem().Kind() == reflect.Ptr &&
val.Type().Elem().Elem().Kind() == reflect.Struct) {

View File

@ -1426,3 +1426,28 @@ func TestPointer2Pointer(t *testing.T) {
c := &b
_ = Map(&c)
}
func TestMap_InterfaceTypeWithMapValue(t *testing.T) {
type A struct {
Name string `structs:"name"`
Ip string `structs:"ip"`
Query string `structs:"query"`
Payload interface{} `structs:"payload"`
}
a := A{
Name: "test",
Ip: "127.0.0.1",
Query: "",
Payload: map[string]string{"test_param": "test_param"},
}
defer func() {
err := recover()
if err != nil {
t.Error("Converting Map with an interface{} type with map value should not panic")
}
}()
_ = Map(a)
}