diff options
| author | Josh Bleecher Snyder <josharian@gmail.com> | 2014-04-08 14:55:12 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2014-04-08 14:55:12 -0400 |
| commit | e79bab30a58e5d74ae2f6f0a2c7e5b789c8b219a (patch) | |
| tree | 3333546968506f21686419b4c0fae036a21d8648 /src/pkg/encoding | |
| parent | 4b42ad2559db444b6a0d4c76aa08f063085485d5 (diff) | |
| download | go-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.go | 9 | ||||
| -rw-r--r-- | src/pkg/encoding/xml/read_test.go | 27 |
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) + } +} |
