Skip to content

Commit

Permalink
Merge pull request #66 from mxmsk/nested-easyjson-marshal
Browse files Browse the repository at this point in the history
Allow interface{} fields to be marshaled using easyjson.Marshaler
  • Loading branch information
vstarodub committed Dec 12, 2016
2 parents 304d3dc + ef80de4 commit 9d6630d
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 4 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
4 changes: 3 additions & 1 deletion gen/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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+"))")
Expand Down
9 changes: 6 additions & 3 deletions gen/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -59,6 +60,7 @@ func NewGenerator(filename string) *Generator {
imports: map[string]string{
pkgWriter: "jwriter",
pkgLexer: "jlexer",
pkgEasyjson: "easyjson",
"encoding/json": "json",
},
fieldNamer: DefaultFieldNamer{},
Expand Down Expand Up @@ -159,9 +161,10 @@ 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(")")

fmt.Println()
Expand Down
23 changes: 23 additions & 0 deletions tests/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,26 @@ 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)
}
}
}
25 changes: 25 additions & 0 deletions tests/nested_easy.go
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 9d6630d

Please sign in to comment.