Skip to content

Commit

Permalink
Merge pull request #196 from mitchellh/b-interface-value
Browse files Browse the repository at this point in the history
If interface value is not addressable, make copy and set
  • Loading branch information
mitchellh committed Jun 7, 2020
2 parents 5ffcd79 + 93663c4 commit 7c2237a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
29 changes: 28 additions & 1 deletion mapstructure.go
Expand Up @@ -463,7 +463,34 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
// value to "data" of that type.
func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
if val.IsValid() && val.Elem().IsValid() {
return d.decode(name, data, val.Elem())
elem := val.Elem()

// If we can't address this element, then its not writable. Instead,
// we make a copy of the value (which is a pointer and therefore
// writable), decode into that, and replace the whole value.
copied := false
if !elem.CanAddr() {
copied = true

// Make *T
copy := reflect.New(elem.Type())

// *T = elem
copy.Elem().Set(elem)

// Set elem so we decode into it
elem = copy
}

// Decode. If we have an error then return. We also return right
// away if we're not a copy because that means we decoded directly.
if err := d.decode(name, data, elem); err != nil || !copied {
return err
}

// If we're a copy, we need to set te final result
val.Set(elem.Elem())
return nil
}

dataVal := reflect.ValueOf(data)
Expand Down
22 changes: 22 additions & 0 deletions mapstructure_test.go
Expand Up @@ -375,6 +375,28 @@ func TestBasic_interfaceStruct(t *testing.T) {
}
}

// Issue 187
func TestBasic_interfaceStructNonPtr(t *testing.T) {
t.Parallel()

input := map[string]interface{}{
"vstring": "foo",
}

var iface interface{} = Basic{}
err := Decode(input, &iface)
if err != nil {
t.Fatalf("got an err: %s", err)
}

expected := Basic{
Vstring: "foo",
}
if !reflect.DeepEqual(iface, expected) {
t.Fatalf("bad: %#v", iface)
}
}

func TestDecode_BasicSquash(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 7c2237a

Please sign in to comment.