From ef252ae4074006fe9d77c9f26c2bdc0bc1af2656 Mon Sep 17 00:00:00 2001 From: dd Date: Thu, 13 Oct 2016 14:28:25 +0300 Subject: [PATCH 1/3] Fix unmarshaling struct with interface field which is a pointer to a struct --- gen/decoder.go | 9 +++++++-- gen/generator.go | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/gen/decoder.go b/gen/decoder.go index 681584f..dafce79 100644 --- a/gen/decoder.go +++ b/gen/decoder.go @@ -212,8 +212,13 @@ func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags field if t.NumMethod() != 0 { return fmt.Errorf("interface type %v not supported: only interface{} is allowed", t) } - fmt.Fprintln(g.out, ws+out+" = in.Interface()") - + fmt.Fprintln(g.out, ws+"if m, ok := "+out+".(easyjson.Unmarshaler); ok {") + fmt.Fprintln(g.out, ws+"m.UnmarshalEasyJSON(in)") + fmt.Fprintln(g.out, ws+"} else if m, ok := "+out+".(json.Unmarshaler); ok {") + fmt.Fprintln(g.out, ws+"m.UnmarshalJSON(in.Raw())") + fmt.Fprintln(g.out, ws+"} else {") + fmt.Fprintln(g.out, ws+" "+out+" = in.Interface()") + fmt.Fprintln(g.out, ws+"}") default: return fmt.Errorf("don't know how to decode %v", t) } diff --git a/gen/generator.go b/gen/generator.go index ed386f7..3eb8b72 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -15,6 +15,7 @@ import ( const pkgWriter = "github.com/mailru/easyjson/jwriter" const pkgLexer = "github.com/mailru/easyjson/jlexer" +const pkgEasyJson = "github.com/mailru/easyjson" // FieldNamer defines a policy for generating names for struct fields. type FieldNamer interface { @@ -59,6 +60,7 @@ func NewGenerator(filename string) *Generator { imports: map[string]string{ pkgWriter: "jwriter", pkgLexer: "jlexer", + pkgEasyJson: "easyjson", "encoding/json": "json", }, fieldNamer: DefaultFieldNamer{}, @@ -162,6 +164,7 @@ func (g *Generator) printHeader() { fmt.Println(" _ = json.RawMessage{}") fmt.Println(" _ = jlexer.Lexer{}") fmt.Println(" _ = jwriter.Writer{}") + fmt.Println(" _ easyjson.Marshaler") fmt.Println(")") fmt.Println() From 532bbefda844dd63ca8e883e7ee938c70f4c1b8d Mon Sep 17 00:00:00 2001 From: dd Date: Fri, 14 Oct 2016 11:45:40 +0300 Subject: [PATCH 2/3] Fix unmarshaling struct with interface field which is a pointer to a struct (part 2: test) --- tests/basic_test.go | 12 ++++++++++++ tests/data.go | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/tests/basic_test.go b/tests/basic_test.go index 3e994ea..1685a17 100644 --- a/tests/basic_test.go +++ b/tests/basic_test.go @@ -156,3 +156,15 @@ func TestUnderflowArray(t *testing.T) { t.Errorf("Unmarshal(%v) = %+v; want %+v", arrayUnderflowString, a, arrayUnderflowValue) } } + +func TestUnmarshalStructWithEmbeddedPtrStruct(t *testing.T) { + var s = StructWithInterface{Field2: &EmbeddedStruct{}} + var err error + err = easyjson.Unmarshal([]byte(structWithInterfaceString), &s) + if err != nil { + t.Errorf("easyjson.Unmarshal() error: %v", err) + } + if !reflect.DeepEqual(s, structWithInterfaceValueFilled) { + t.Errorf("easyjson.Unmarshal() = %#v; want %#v", s, structWithInterfaceValueFilled) + } +} diff --git a/tests/data.go b/tests/data.go index 1716617..baaa633 100644 --- a/tests/data.go +++ b/tests/data.go @@ -624,3 +624,17 @@ type RequiredOptionalStruct struct { FirstName string `json:"first_name,required"` Lastname string `json:"last_name"` } + +type StructWithInterface struct { + Field1 int `json:"f1"` + Field2 interface{} `json:"f2"` + Field3 string `json:"f3"` +} + +type EmbeddedStruct struct { + Field1 int `json:"f1"` + Field2 string `json:"f2"` +} + +var structWithInterfaceString = `{"f1":1,"f2":{"f1":11,"f2":"22"},"f3":"3"}` +var structWithInterfaceValueFilled = StructWithInterface{1, &EmbeddedStruct{11, "22"}, "3"} From 1a546ab49f81715aa533c6c6353e86e2434c287e Mon Sep 17 00:00:00 2001 From: dd Date: Tue, 24 Jan 2017 12:17:06 +0300 Subject: [PATCH 3/3] rename const pkgEasyJson -> pkgEasyJSON --- gen/generator.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gen/generator.go b/gen/generator.go index 691286b..c5c9103 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -15,7 +15,7 @@ import ( const pkgWriter = "github.com/mailru/easyjson/jwriter" const pkgLexer = "github.com/mailru/easyjson/jlexer" -const pkgEasyJson = "github.com/mailru/easyjson" +const pkgEasyJSON = "github.com/mailru/easyjson" // FieldNamer defines a policy for generating names for struct fields. type FieldNamer interface { @@ -60,7 +60,7 @@ func NewGenerator(filename string) *Generator { imports: map[string]string{ pkgWriter: "jwriter", pkgLexer: "jlexer", - pkgEasyJson: "easyjson", + pkgEasyJSON: "easyjson", "encoding/json": "json", }, fieldNamer: DefaultFieldNamer{},