mirror of
https://github.com/json-iterator/go.git
synced 2025-04-01 21:24:21 +02:00
fix #219 should check real value for empty instead of just the pointer for nested field
This commit is contained in:
parent
6dad2de6cc
commit
0ab880662f
@ -266,9 +266,9 @@ func describeStruct(cfg *frozenConfig, prefix string, typ reflect.Type) *StructD
|
||||
for _, binding := range structDescriptor.Fields {
|
||||
binding.levels = append([]int{i}, binding.levels...)
|
||||
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
|
||||
binding.Encoder = &OptionalEncoder{binding.Encoder}
|
||||
binding.Encoder = &dereferenceEncoder{binding.Encoder}
|
||||
binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty}
|
||||
binding.Decoder = &deferenceDecoder{field.Type.Elem(), binding.Decoder}
|
||||
binding.Decoder = &dereferenceDecoder{field.Type.Elem(), binding.Decoder}
|
||||
binding.Decoder = &structFieldDecoder{&field, binding.Decoder}
|
||||
embeddedBindings = append(embeddedBindings, binding)
|
||||
}
|
||||
|
@ -43,13 +43,13 @@ func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
}
|
||||
}
|
||||
|
||||
type deferenceDecoder struct {
|
||||
type dereferenceDecoder struct {
|
||||
// only to deference a pointer
|
||||
valueType reflect.Type
|
||||
valueDecoder ValDecoder
|
||||
}
|
||||
|
||||
func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||
//pointer to null, we have to allocate memory to hold the value
|
||||
value := reflect.New(decoder.valueType)
|
||||
@ -82,6 +82,26 @@ func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||
return *((*unsafe.Pointer)(ptr)) == nil
|
||||
}
|
||||
|
||||
type dereferenceEncoder struct {
|
||||
ValueEncoder ValEncoder
|
||||
}
|
||||
|
||||
func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||
stream.WriteNil()
|
||||
} else {
|
||||
encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
|
||||
}
|
||||
}
|
||||
|
||||
func (encoder *dereferenceEncoder) EncodeInterface(val interface{}, stream *Stream) {
|
||||
WriteToStream(val, stream, encoder)
|
||||
}
|
||||
|
||||
func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||
return encoder.ValueEncoder.IsEmpty(*((*unsafe.Pointer)(ptr)))
|
||||
}
|
||||
|
||||
type optionalMapEncoder struct {
|
||||
valueEncoder ValEncoder
|
||||
}
|
||||
|
@ -158,6 +158,28 @@ func Test_ignore_field_on_not_valid_type(t *testing.T) {
|
||||
should.Equal(`{"field-1":"hello world"}`, str)
|
||||
}
|
||||
|
||||
func Test_nested_field_omit_empty(t *testing.T) {
|
||||
should := require.New(t)
|
||||
type S1 struct {
|
||||
F1 string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type S2 struct {
|
||||
*S1
|
||||
F2 string `json:",omitempty"`
|
||||
}
|
||||
s1 := &S1{
|
||||
//F1: "abc",
|
||||
}
|
||||
s2 := &S2{
|
||||
S1: s1,
|
||||
F2: "123",
|
||||
}
|
||||
str, err := MarshalToString(s2)
|
||||
should.Nil(err)
|
||||
should.Equal(`{"F2":"123"}`, str)
|
||||
}
|
||||
|
||||
func Test_recursive_struct(t *testing.T) {
|
||||
should := require.New(t)
|
||||
type TestObject struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user