diff --git a/Makefile b/Makefile index 5a95104..e2c9bd6 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,7 @@ generate: root build .root/bin/easyjson -snake_case .root/src/$(PKG)/tests/snake.go .root/bin/easyjson -omit_empty .root/src/$(PKG)/tests/omitempty.go .root/bin/easyjson -build_tags=use_easyjson .root/src/$(PKG)/benchmark/data.go + .root/bin/easyjson .root/src/$(PKG)/tests/nested_easy.go test: generate root go test \ diff --git a/gen/encoder.go b/gen/encoder.go index 2aec3c6..30dbbc9 100644 --- a/gen/encoder.go +++ b/gen/encoder.go @@ -199,7 +199,9 @@ func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldT if t.NumMethod() != 0 { return fmt.Errorf("interface type %v not supported: only interface{} is allowed", t) } - fmt.Fprintln(g.out, ws+"if m, ok := "+in+".(json.Marshaler); ok {") + fmt.Fprintln(g.out, ws+"if m, ok := "+in+".(easyjson.Marshaler); ok {") + fmt.Fprintln(g.out, ws+" m.MarshalEasyJSON(out)") + fmt.Fprintln(g.out, ws+"} else if m, ok := "+in+".(json.Marshaler); ok {") fmt.Fprintln(g.out, ws+" out.Raw(m.MarshalJSON())") fmt.Fprintln(g.out, ws+"} else {") fmt.Fprintln(g.out, ws+" out.Raw(json.Marshal("+in+"))") diff --git a/gen/generator.go b/gen/generator.go index 3eb8b72..691286b 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -161,9 +161,9 @@ func (g *Generator) printHeader() { fmt.Println("") fmt.Println("// suppress unused package warning") fmt.Println("var (") - fmt.Println(" _ = json.RawMessage{}") - fmt.Println(" _ = jlexer.Lexer{}") - fmt.Println(" _ = jwriter.Writer{}") + fmt.Println(" _ *json.RawMessage") + fmt.Println(" _ *jlexer.Lexer") + fmt.Println(" _ *jwriter.Writer") fmt.Println(" _ easyjson.Marshaler") fmt.Println(")") diff --git a/parser/parser_windows.go b/parser/parser_windows.go index 76140a9..64974aa 100644 --- a/parser/parser_windows.go +++ b/parser/parser_windows.go @@ -11,7 +11,7 @@ func normalizePath(path string) string { return strings.Replace(path, "\\", "/", -1) } -func getPkgPath(fname string) (string, error) { +func getPkgPath(fname string, isDir bool) (string, error) { if !path.IsAbs(fname) { pwd, err := os.Getwd() if err != nil { @@ -25,7 +25,11 @@ func getPkgPath(fname string) (string, error) { for _, p := range strings.Split(os.Getenv("GOPATH"), ";") { prefix := path.Join(normalizePath(p), "src") + "/" if rel := strings.TrimPrefix(fname, prefix); rel != fname { - return path.Dir(rel), nil + if !isDir { + return path.Dir(rel), nil + } else { + return path.Clean(rel), nil + } } } diff --git a/tests/basic_test.go b/tests/basic_test.go index 07b5458..5798ee4 100644 --- a/tests/basic_test.go +++ b/tests/basic_test.go @@ -184,6 +184,29 @@ func TestEncodingFlags(t *testing.T) { } +func TestNestedEasyJsonMarshal(t *testing.T) { + n := map[string]*NestedEasyMarshaler{ + "Value": {}, + "Slice1": {}, + "Slice2": {}, + "Map1": {}, + "Map2": {}, + } + + ni := NestedInterfaces{ + Value: n["Value"], + Slice: []interface{}{n["Slice1"], n["Slice2"]}, + Map: map[string]interface{}{"1": n["Map1"], "2": n["Map2"]}, + } + easyjson.Marshal(ni) + + for k, v := range n { + if !v.EasilyMarshaled { + t.Errorf("Nested interface %s wasn't easily marshaled", k) + } + } +} + func TestUnmarshalStructWithEmbeddedPtrStruct(t *testing.T) { var s = StructWithInterface{Field2: &EmbeddedStruct{}} var err error diff --git a/tests/nested_easy.go b/tests/nested_easy.go new file mode 100644 index 0000000..6309a49 --- /dev/null +++ b/tests/nested_easy.go @@ -0,0 +1,25 @@ +package tests + +import ( + "github.com/mailru/easyjson" + "github.com/mailru/easyjson/jwriter" +) + +//easyjson:json +type NestedInterfaces struct { + Value interface{} + Slice []interface{} + Map map[string]interface{} +} + +type NestedEasyMarshaler struct { + EasilyMarshaled bool +} + +var _ easyjson.Marshaler = &NestedEasyMarshaler{} + +func (i *NestedEasyMarshaler) MarshalEasyJSON(w *jwriter.Writer) { + // We use this method only to indicate that easyjson.Marshaler + // interface was really used while encoding. + i.EasilyMarshaled = true +} \ No newline at end of file