]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/xml: unmarshal into interfaces
authorJosh Bleecher Snyder <josharian@gmail.com>
Tue, 8 Apr 2014 18:55:12 +0000 (14:55 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 8 Apr 2014 18:55:12 +0000 (14:55 -0400)
Fixes #6836.

LGTM=rsc
R=golang-codereviews, rsc, r, mike
CC=golang-codereviews
https://golang.org/cl/33140043

src/pkg/encoding/xml/read.go
src/pkg/encoding/xml/read_test.go

index 651d13d4d094dd6adba063ac79c82d9117833115..75b9f2ba1b2ee44fad5e1a72e53058c988364db2 100644 (file)
@@ -284,6 +284,15 @@ func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
                }
        }
 
+       // Load value from interface, but only if the result will be
+       // usefully addressable.
+       if val.Kind() == reflect.Interface && !val.IsNil() {
+               e := val.Elem()
+               if e.Kind() == reflect.Ptr && !e.IsNil() {
+                       val = e
+               }
+       }
+
        if val.Kind() == reflect.Ptr {
                if val.IsNil() {
                        val.Set(reflect.New(val.Type().Elem()))
index 1404c900f50506977c98c3f6d80f02cd0c841fa3..01f55d0dd00cec4ae81876f3f5854678705655ae 100644 (file)
@@ -685,3 +685,30 @@ func TestUnmarshaler(t *testing.T) {
                t.Errorf("m=%#+v\n", m)
        }
 }
+
+type Pea struct {
+       Cotelydon string
+}
+
+type Pod struct {
+       Pea interface{} `xml:"Pea"`
+}
+
+// https://code.google.com/p/go/issues/detail?id=6836
+func TestUnmarshalIntoInterface(t *testing.T) {
+       pod := new(Pod)
+       pod.Pea = new(Pea)
+       xml := `<Pod><Pea><Cotelydon>Green stuff</Cotelydon></Pea></Pod>`
+       err := Unmarshal([]byte(xml), pod)
+       if err != nil {
+               t.Fatalf("failed to unmarshal %q: %v", xml, err)
+       }
+       pea, ok := pod.Pea.(*Pea)
+       if !ok {
+               t.Fatalf("unmarshalled into wrong type: have %T want *Pea", pod.Pea)
+       }
+       have, want := pea.Cotelydon, "Green stuff"
+       if have != want {
+               t.Errorf("failed to unmarshal into interface, have %q want %q", have, want)
+       }
+}