Support pointers to structs as well
diff --git a/mapstructure.go b/mapstructure.go index 937c205..49362eb 100644 --- a/mapstructure.go +++ b/mapstructure.go
@@ -76,7 +76,7 @@ } func decodeStruct(name string, data interface{}, val reflect.Value) error { - dataVal := reflect.ValueOf(data) + dataVal := reflect.Indirect(reflect.ValueOf(data)) dataValKind := dataVal.Kind() if dataValKind != reflect.Map { return fmt.Errorf("'%s' expected a map, got '%s'", name, dataValKind) @@ -91,7 +91,7 @@ // At this point we know that data is a map with string keys, so // we can properly cast it here. - m, ok := data.(map[string]interface{}) + m, ok := dataVal.Interface().(map[string]interface{}) if !ok { panic("data could not be cast as map[string]interface{}") }
diff --git a/mapstructure_test.go b/mapstructure_test.go index a55953b..82ee210 100644 --- a/mapstructure_test.go +++ b/mapstructure_test.go
@@ -87,6 +87,46 @@ } } +func TestNestedTypePointer(t *testing.T) { + t.Parallel() + + input := map[string]interface{}{ + "vfoo": "foo", + "vbar": &map[string]interface{}{ + "vstring": "foo", + "vint": 42, + "vbool": true, + }, + } + + var result Nested + err := MapToStruct(input, &result) + if err != nil { + t.Errorf("got an err: %s", err.Error()) + t.FailNow() + } + + if result.Vfoo != "foo" { + t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo) + } + + if result.Vbar.Vstring != "foo" { + t.Errorf("vstring value should be 'foo': %#v", result.Vbar.Vstring) + } + + if result.Vbar.Vint != 42 { + t.Errorf("vint value should be 42: %#v", result.Vbar.Vint) + } + + if result.Vbar.Vbool != true { + t.Errorf("vbool value should be true: %#v", result.Vbar.Vbool) + } + + if result.Vbar.Vextra != "" { + t.Errorf("vextra value should be empty: %#v", result.Vbar.Vextra) + } +} + func TestInvalidType(t *testing.T) { t.Parallel()