mapstructure
mapstructure copied to clipboard
Wrong target type restriction when decoding struct to map
When the target map to decode the result to is strongly typed, the decoding process fails, even if the map type matches the source structure.
func TestDecode_structToTypedMap(t *testing.T) {
type SourceChild struct {
String string `mapstructure:"string"`
}
type SourceParent struct {
Child SourceChild `mapstructure:"child"`
}
var target map[string]map[string]interface{} // This is the reason the test fails
//var target map[string]interface{} // With this variant it works
source := SourceParent{
Child: SourceChild{
String: "hello",
},
}
if err := Decode(source, &target); err != nil {
t.Fatalf("got error: %s", err)
}
expected := map[string]interface{}{
"child": map[string]interface{}{
"string": "hello",
},
}
if !reflect.DeepEqual(target, expected) {
t.Fatalf("bad: \nexpected: %#v\nresult: %#v", expected, target)
}
}
Produces:
=== RUN TestDecode_structToTypedMap
mapstructure_test.go:2884: got error: cannot assign type 'mapstructure.SourceChild' to map value field of type 'map[string]interface {}'
--- FAIL: TestDecode_structToTypedMap (0.00s)
As the target sutructure matches the needs of the decoding process, I would expect this to work.
mapstructure version bf980b35cac4dfd34e05254ee5aba086504c3f96 go version go1.18.7 linux/amd64
As far as I understand, the issue is here : https://github.com/mitchellh/mapstructure/blob/main/mapstructure.go#L976
The type of the map field is not the same as the parent (owning) map. This only works if the type is generic (interface{}).