Repository: mitchellh/mapstructure (go)

Issue:
Support struct wrapped in interface as target for decoding
Similar to #186, mapstructure is not handling structs assigned to interfaces:

```go
var cc interface{}
cc = struct{ Foo, Bar string }{}

decoderConfig := &mapstructure.DecoderConfig{Result: &cc, ErrorUnused: true}
decoder, err := mapstructure.NewDecoder(decoderConfig)
if err != nil {
	log.Fatal(err)
}

conf := map[string]string{
	"foo": "bar",
	"bar": "baz",
}

if err := decoder.Decode(conf); err != nil {
	log.Fatal(err)
}
```

Will give 

    * '' has invalid keys: bar, foo

Would this be something worthwile to address with a PR or are there constraints that would prevent handling this case?

Pull request description:
If interface value is not addressable, make copy and set
This fixes #187. If the value of an interface is not addressable, we
can't decode into it because we can't replace any keys. To work around
this, we copy the value, decode into that, and then replace the full
value.

Patch:
diff --git a/mapstructure.go b/mapstructure.go
index 84beaab..b384d9d 100644
--- a/mapstructure.go
+++ b/mapstructure.go
@@ -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)


Test patch:
diff --git a/mapstructure_test.go b/mapstructure_test.go
index 1701394..63614e8 100644
--- a/mapstructure_test.go
+++ b/mapstructure_test.go
@@ -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()