diff --git a/gen/encoder.go b/gen/encoder.go index 06303e0..2aec3c6 100644 --- a/gen/encoder.go +++ b/gen/encoder.go @@ -121,7 +121,7 @@ func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldT if t.Elem().Kind() == reflect.Uint8 { fmt.Fprintln(g.out, ws+"out.Base64Bytes("+in+")") } else { - fmt.Fprintln(g.out, ws+"if "+in+" == nil {") + fmt.Fprintln(g.out, ws+"if "+in+" == nil && (out.Flags & jwriter.NilSliceAsEmpty) == 0 {") fmt.Fprintln(g.out, ws+` out.RawString("null")`) fmt.Fprintln(g.out, ws+"} else {") fmt.Fprintln(g.out, ws+" out.RawByte('[')") @@ -178,7 +178,7 @@ func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldT } tmpVar := g.uniqueVarName() - fmt.Fprintln(g.out, ws+"if "+in+" == nil {") + fmt.Fprintln(g.out, ws+"if "+in+" == nil && (out.Flags & jwriter.NilMapAsEmpty) == 0 {") fmt.Fprintln(g.out, ws+" out.RawString(`null`)") fmt.Fprintln(g.out, ws+"} else {") fmt.Fprintln(g.out, ws+" out.RawByte('{')") diff --git a/jwriter/writer.go b/jwriter/writer.go index acd670f..a3ef534 100644 --- a/jwriter/writer.go +++ b/jwriter/writer.go @@ -10,8 +10,19 @@ import ( "github.com/mailru/easyjson/buffer" ) +// Flags describe various encoding options. The behavior may be actually implemented in the encoder, but +// Flags field in Writer is used to set and pass them around. +type Flags int + +const ( + NilMapAsEmpty Flags = 1 << iota // Encode nil map as '{}' rather than 'null'. + NilSliceAsEmpty // Encode nil slice as '[]' rather than 'null'. +) + // Writer is a JSON writer. type Writer struct { + Flags Flags + Error error Buffer buffer.Buffer } diff --git a/tests/basic_test.go b/tests/basic_test.go index 3e994ea..5633e3d 100644 --- a/tests/basic_test.go +++ b/tests/basic_test.go @@ -156,3 +156,30 @@ func TestUnderflowArray(t *testing.T) { t.Errorf("Unmarshal(%v) = %+v; want %+v", arrayUnderflowString, a, arrayUnderflowValue) } } + +func TestEncodingFlags(t *testing.T) { + for i, test := range []struct { + Flags jwriter.Flags + In easyjson.Marshaler + Want string + }{ + {0, EncodingFlagsTestMap{}, `{"F":null}`}, + {0, EncodingFlagsTestSlice{}, `{"F":null}`}, + {jwriter.NilMapAsEmpty, EncodingFlagsTestMap{}, `{"F":{}}`}, + {jwriter.NilSliceAsEmpty, EncodingFlagsTestSlice{}, `{"F":[]}`}, + } { + w := &jwriter.Writer{Flags: test.Flags} + test.In.MarshalEasyJSON(w) + + data, err := w.BuildBytes() + if err != nil { + t.Errorf("[%v] easyjson.Marshal(%+v) error: %v", i, test.In, err) + } + + v := string(data) + if v != test.Want { + t.Errorf("[%v] easyjson.Marshal(%+v) = %v; want %v", i, test.In, v, test.Want) + } + } + +} diff --git a/tests/data.go b/tests/data.go index 1716617..a46a4a5 100644 --- a/tests/data.go +++ b/tests/data.go @@ -624,3 +624,13 @@ type RequiredOptionalStruct struct { FirstName string `json:"first_name,required"` Lastname string `json:"last_name"` } + +//easyjson:json +type EncodingFlagsTestMap struct { + F map[string]string +} + +//easyjson:json +type EncodingFlagsTestSlice struct { + F []string +}