aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/encoding
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2014-04-08 14:55:12 -0400
committerRuss Cox <rsc@golang.org>2014-04-08 14:55:12 -0400
commite79bab30a58e5d74ae2f6f0a2c7e5b789c8b219a (patch)
tree3333546968506f21686419b4c0fae036a21d8648 /src/pkg/encoding
parent4b42ad2559db444b6a0d4c76aa08f063085485d5 (diff)
downloadgo-e79bab30a58e5d74ae2f6f0a2c7e5b789c8b219a.tar.xz
encoding/xml: unmarshal into interfaces
Fixes #6836. LGTM=rsc R=golang-codereviews, rsc, r, mike CC=golang-codereviews https://golang.org/cl/33140043
Diffstat (limited to 'src/pkg/encoding')
-rw-r--r--src/pkg/encoding/xml/read.go9
-rw-r--r--src/pkg/encoding/xml/read_test.go27
2 files changed, 36 insertions, 0 deletions
diff --git a/src/pkg/encoding/xml/read.go b/src/pkg/encoding/xml/read.go
index 651d13d4d0..75b9f2ba1b 100644
--- a/src/pkg/encoding/xml/read.go
+++ b/src/pkg/encoding/xml/read.go
@@ -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()))
diff --git a/src/pkg/encoding/xml/read_test.go b/src/pkg/encoding/xml/read_test.go
index 1404c900f5..01f55d0dd0 100644
--- a/src/pkg/encoding/xml/read_test.go
+++ b/src/pkg/encoding/xml/read_test.go
@@ -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)
+ }
+}