mirror of
https://github.com/netbirdio/easyjson.git
synced 2026-05-22 18:44:42 -07:00
Standard encoding/json marshaller interface support.
This commit is contained in:
@@ -20,8 +20,9 @@ type Generator struct {
|
||||
PkgPath, PkgName string
|
||||
Types []string
|
||||
|
||||
SnakeCase bool
|
||||
OmitEmpty bool
|
||||
NoStdMarshalers bool
|
||||
SnakeCase bool
|
||||
OmitEmpty bool
|
||||
|
||||
OutName string
|
||||
BuildTags string
|
||||
@@ -78,6 +79,9 @@ func (g *Generator) writeMain() (path string, err error) {
|
||||
if g.OmitEmpty {
|
||||
fmt.Fprintln(f, " g.OmitEmpty()")
|
||||
}
|
||||
if g.NoStdMarshalers {
|
||||
fmt.Fprintln(f, " g.NoStdMarshalers()")
|
||||
}
|
||||
for _, v := range g.Types {
|
||||
fmt.Fprintln(f, " g.Add(pkg."+v+"{})")
|
||||
}
|
||||
|
||||
+11
-9
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
var buildTags = flag.String("build_tags", "", "build tags to add to generated file")
|
||||
var snakeCase = flag.Bool("snake_case", false, "use snake_case names instead of CamelCase by default")
|
||||
var noStdMarshalers = flag.Bool("no_std_marshalers", false, "don't generate MarshalJSON/UnmarshalJSON methods")
|
||||
var omitEmpty = flag.Bool("omit_empty", false, "omit empty fields by default")
|
||||
var allStructs = flag.Bool("all", false, "generate un-/marshallers for all structs in a file")
|
||||
var leaveTemps = flag.Bool("leave_temps", false, "do not delete temporary files")
|
||||
@@ -31,15 +32,16 @@ func generate(fname string) (err error) {
|
||||
}
|
||||
|
||||
g := bootstrap.Generator{
|
||||
BuildTags: *buildTags,
|
||||
PkgPath: p.PkgPath,
|
||||
PkgName: p.PkgName,
|
||||
Types: p.StructNames,
|
||||
SnakeCase: *snakeCase,
|
||||
OmitEmpty: *omitEmpty,
|
||||
LeaveTemps: *leaveTemps,
|
||||
OutName: outName,
|
||||
StubsOnly: *stubs,
|
||||
BuildTags: *buildTags,
|
||||
PkgPath: p.PkgPath,
|
||||
PkgName: p.PkgName,
|
||||
Types: p.StructNames,
|
||||
SnakeCase: *snakeCase,
|
||||
NoStdMarshalers: *noStdMarshalers,
|
||||
OmitEmpty: *omitEmpty,
|
||||
LeaveTemps: *leaveTemps,
|
||||
OutName: outName,
|
||||
StubsOnly: *stubs,
|
||||
}
|
||||
|
||||
if err := g.Run(); err != nil {
|
||||
|
||||
+17
-5
@@ -1,6 +1,7 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -42,6 +43,14 @@ func (g *Generator) genTypeDecoder(t reflect.Type, out string, indent int) error
|
||||
return nil
|
||||
}
|
||||
|
||||
unmarshalerIface = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
|
||||
if reflect.PtrTo(t).Implements(unmarshalerIface) {
|
||||
fmt.Fprintln(g.out, ws+"if data := in.Raw(); in.Ok() {")
|
||||
fmt.Fprintln(g.out, ws+" in.AddError( ("+out+").UnmarshalJSON(data) )")
|
||||
fmt.Fprintln(g.out, ws+"}")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check whether type is primitive, needs to be done after interface check.
|
||||
if dec := primitiveDecoders[t.Kind()]; dec != "" {
|
||||
fmt.Fprintln(g.out, ws+out+" = "+dec)
|
||||
@@ -224,11 +233,14 @@ func (g *Generator) genStructUnmarshaller(t reflect.Type) error {
|
||||
fname := g.getStructDecoderName(t)
|
||||
typ := g.getType(t)
|
||||
|
||||
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalJSON(data []byte) error {")
|
||||
fmt.Fprintln(g.out, " r := jlexer.Lexer{Data: data}")
|
||||
fmt.Fprintln(g.out, " "+fname+"(&r, v)")
|
||||
fmt.Fprintln(g.out, " return r.Error()")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
if !g.noStdMarshalers {
|
||||
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalJSON(data []byte) error {")
|
||||
fmt.Fprintln(g.out, " r := jlexer.Lexer{Data: data}")
|
||||
fmt.Fprintln(g.out, " "+fname+"(&r, v)")
|
||||
fmt.Fprintln(g.out, " return r.Error()")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalEasyJSON(l *jlexer.Lexer) {")
|
||||
fmt.Fprintln(g.out, " "+fname+"(l, v)")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
|
||||
+14
-5
@@ -1,6 +1,7 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
@@ -39,6 +40,12 @@ func (g *Generator) genTypeEncoder(t reflect.Type, in string, indent int) error
|
||||
return nil
|
||||
}
|
||||
|
||||
marshalerIface = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
|
||||
if reflect.PtrTo(t).Implements(marshalerIface) {
|
||||
fmt.Fprintln(g.out, ws+"out.Raw( ("+in+").MarshalJSON() )")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check whether type is primitive, needs to be done after interface check.
|
||||
if enc := primitiveEncoders[t.Kind()]; enc != "" {
|
||||
fmt.Fprintln(g.out, ws+enc+"("+in+")")
|
||||
@@ -198,11 +205,13 @@ func (g *Generator) genStructMarshaller(t reflect.Type) error {
|
||||
fname := g.getStructEncoderName(t)
|
||||
typ := g.getType(t)
|
||||
|
||||
fmt.Fprintln(g.out, "func (v *"+typ+") MarshalJSON() ([]byte, error) {")
|
||||
fmt.Fprintln(g.out, " w := jwriter.Writer{}")
|
||||
fmt.Fprintln(g.out, " "+fname+"(&w, v)")
|
||||
fmt.Fprintln(g.out, " return w.Buffer.BuildBytes(), w.Error")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
if !g.noStdMarshalers {
|
||||
fmt.Fprintln(g.out, "func (v *"+typ+") MarshalJSON() ([]byte, error) {")
|
||||
fmt.Fprintln(g.out, " w := jwriter.Writer{}")
|
||||
fmt.Fprintln(g.out, " "+fname+"(&w, v)")
|
||||
fmt.Fprintln(g.out, " return w.Buffer.BuildBytes(), w.Error")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, "func (v *"+typ+") MarshalEasyJSON(w *jwriter.Writer) {")
|
||||
fmt.Fprintln(g.out, " "+fname+"(w, v)")
|
||||
|
||||
+9
-2
@@ -29,8 +29,9 @@ type Generator struct {
|
||||
|
||||
varCounter int
|
||||
|
||||
omitEmpty bool
|
||||
namer FieldNamer
|
||||
noStdMarshalers bool
|
||||
omitEmpty bool
|
||||
namer FieldNamer
|
||||
|
||||
// package path to local alias map for tracking imports
|
||||
imports map[string]string
|
||||
@@ -85,6 +86,12 @@ func (g *Generator) UseSnakeCase() {
|
||||
g.namer = SnakeCaseFieldNamer{}
|
||||
}
|
||||
|
||||
// NoStdMarshalers instructs not to generate standard MarshalJSON/UnmarshalJSON
|
||||
// methods (only the custom interface).
|
||||
func (g *Generator) NoStdMarshalers() {
|
||||
g.noStdMarshalers = true
|
||||
}
|
||||
|
||||
// OmitEmpty triggers `json=",omitempty"` behaviour by default.
|
||||
func (g *Generator) OmitEmpty() {
|
||||
g.omitEmpty = true
|
||||
|
||||
@@ -23,6 +23,7 @@ var testCases = []struct {
|
||||
{&omitEmptyDefaultValue, omitEmptyDefaultString},
|
||||
{&optsValue, optsString},
|
||||
{&rawValue, rawString},
|
||||
{&stdMarshalerValue, stdMarshalerString},
|
||||
}
|
||||
|
||||
func TestMarshal(t *testing.T) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package tests
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/mailru/easyjson/opt"
|
||||
@@ -200,3 +201,10 @@ var rawString = `{` +
|
||||
`"Field":{"a" : "b"},` +
|
||||
`"Field2":"test"` +
|
||||
`}`
|
||||
|
||||
type StdMarshaler struct {
|
||||
T time.Time
|
||||
}
|
||||
|
||||
var stdMarshalerValue = StdMarshaler{T: time.Date(2016, 01, 02, 14, 15, 10, 0, time.UTC)}
|
||||
var stdMarshalerString = `{"T":"2016-01-02T14:15:10Z"}`
|
||||
|
||||
Reference in New Issue
Block a user