1
0
mirror of https://github.com/json-iterator/go.git synced 2025-05-13 21:36:29 +02:00

Merge pull request #189 from ggaaooppeenngg/compatible-with-map

Fix standard compatiblility
This commit is contained in:
Tao Wen 2017-10-26 18:39:38 -05:00 committed by GitHub
commit fbd210edfc
3 changed files with 43 additions and 4 deletions

View File

@ -18,3 +18,23 @@ func TestEncoderHasTrailingNewline(t *testing.T) {
stdenc.Encode(1) stdenc.Encode(1)
should.Equal(stdbuf.Bytes(), buf.Bytes()) should.Equal(stdbuf.Bytes(), buf.Bytes())
} }
// Non-nil but empty map should be ignored.
func TestOmitempty(t *testing.T) {
o := struct {
A string `json:"a,omitempty"`
B string `json:"b,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"`
}{
A: "a",
B: "b",
Annotations: map[string]string{},
}
should := require.New(t)
var buf, stdbuf bytes.Buffer
enc := ConfigCompatibleWithStandardLibrary.NewEncoder(&buf)
enc.Encode(o)
stdenc := json.NewEncoder(&stdbuf)
stdenc.Encode(o)
should.Equal(string(stdbuf.Bytes()), string(buf.Bytes()))
}

View File

@ -130,10 +130,28 @@ func (encoder *optionalEncoder) EncodeInterface(val interface{}, stream *Stream)
} }
func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return *((*unsafe.Pointer)(ptr)) == nil
}
type optionalMapEncoder struct {
valueEncoder ValEncoder
}
func (encoder *optionalMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
if *((*unsafe.Pointer)(ptr)) == nil { if *((*unsafe.Pointer)(ptr)) == nil {
return true stream.WriteNil()
} else {
encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
} }
return false }
func (encoder *optionalMapEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *optionalMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
p := *((*unsafe.Pointer)(ptr))
return p == nil || encoder.valueEncoder.IsEmpty(p)
} }
type placeholderEncoder struct { type placeholderEncoder struct {

View File

@ -280,9 +280,10 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
if len(fieldNames) > 0 && err != nil { if len(fieldNames) > 0 && err != nil {
return nil, err return nil, err
} }
// map is stored as pointer in the struct // map is stored as pointer in the struct,
// and treat nil or empty map as empty field
if encoder != nil && field.Type.Kind() == reflect.Map { if encoder != nil && field.Type.Kind() == reflect.Map {
encoder = &optionalEncoder{encoder} encoder = &optionalMapEncoder{encoder}
} }
} }
binding := &Binding{ binding := &Binding{