Check assignability
diff --git a/mapstructure.go b/mapstructure.go index d4a49ed..f1a0c80 100644 --- a/mapstructure.go +++ b/mapstructure.go
@@ -2,6 +2,7 @@ import ( "errors" + "fmt" "reflect" "strings" ) @@ -60,6 +61,15 @@ panic("map value is not valid") } + mapValType := mapVal.Type() + if !mapValType.AssignableTo(field.Type()) { + // If the value in the map can't be assigned to the field + // in the struct, then this is a problem... + return fmt.Errorf( + "field '%s' expected type '%s', got '%s'", + fieldName, field.Type(), mapValType) + } + field.Set(mapVal) }
diff --git a/mapstructure_test.go b/mapstructure_test.go index ec47e70..3ec2a3a 100644 --- a/mapstructure_test.go +++ b/mapstructure_test.go
@@ -4,8 +4,9 @@ type Basic struct { Vstring string - Vint int - Vbool bool + Vint int + Vbool bool + Vextra string } func TestBasicTypes(t *testing.T) { @@ -13,8 +14,8 @@ input := map[string]interface{}{ "vstring": "foo", - "vint": 42, - "vbool": true, + "vint": 42, + "vbool": true, } var result Basic @@ -35,6 +36,29 @@ if result.Vbool != true { t.Errorf("vbool value should be true: %#v", result.Vbool) } + + if result.Vextra != "" { + t.Errorf("vextra value should be empty: %#v", result.Vextra) + } +} + +func TestInvalidType(t *testing.T) { + t.Parallel() + + input := map[string]interface{}{ + "vstring": 42, + } + + var result Basic + err := MapToStruct(input, &result) + if err == nil { + t.Error("error should exist") + t.FailNow() + } + + if err.Error() != "field 'Vstring' expected type 'string', got 'int'" { + t.Errorf("got unexpected error: %s", err) + } } func TestNonPtrValue(t *testing.T) {