Skip to content

Commit 0ab8806

Browse files
committed
fix #219 should check real value for empty instead of just the pointer for nested field
1 parent 6dad2de commit 0ab8806

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

feature_reflect_extension.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ func describeStruct(cfg *frozenConfig, prefix string, typ reflect.Type) *StructD
266266
for _, binding := range structDescriptor.Fields {
267267
binding.levels = append([]int{i}, binding.levels...)
268268
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
269-
binding.Encoder = &OptionalEncoder{binding.Encoder}
269+
binding.Encoder = &dereferenceEncoder{binding.Encoder}
270270
binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty}
271-
binding.Decoder = &deferenceDecoder{field.Type.Elem(), binding.Decoder}
271+
binding.Decoder = &dereferenceDecoder{field.Type.Elem(), binding.Decoder}
272272
binding.Decoder = &structFieldDecoder{&field, binding.Decoder}
273273
embeddedBindings = append(embeddedBindings, binding)
274274
}

feature_reflect_optional.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
4343
}
4444
}
4545

46-
type deferenceDecoder struct {
46+
type dereferenceDecoder struct {
4747
// only to deference a pointer
4848
valueType reflect.Type
4949
valueDecoder ValDecoder
5050
}
5151

52-
func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
52+
func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
5353
if *((*unsafe.Pointer)(ptr)) == nil {
5454
//pointer to null, we have to allocate memory to hold the value
5555
value := reflect.New(decoder.valueType)
@@ -82,6 +82,26 @@ func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
8282
return *((*unsafe.Pointer)(ptr)) == nil
8383
}
8484

85+
type dereferenceEncoder struct {
86+
ValueEncoder ValEncoder
87+
}
88+
89+
func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
90+
if *((*unsafe.Pointer)(ptr)) == nil {
91+
stream.WriteNil()
92+
} else {
93+
encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
94+
}
95+
}
96+
97+
func (encoder *dereferenceEncoder) EncodeInterface(val interface{}, stream *Stream) {
98+
WriteToStream(val, stream, encoder)
99+
}
100+
101+
func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
102+
return encoder.ValueEncoder.IsEmpty(*((*unsafe.Pointer)(ptr)))
103+
}
104+
85105
type optionalMapEncoder struct {
86106
valueEncoder ValEncoder
87107
}

jsoniter_object_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,28 @@ func Test_ignore_field_on_not_valid_type(t *testing.T) {
158158
should.Equal(`{"field-1":"hello world"}`, str)
159159
}
160160

161+
func Test_nested_field_omit_empty(t *testing.T) {
162+
should := require.New(t)
163+
type S1 struct {
164+
F1 string `json:",omitempty"`
165+
}
166+
167+
type S2 struct {
168+
*S1
169+
F2 string `json:",omitempty"`
170+
}
171+
s1 := &S1{
172+
//F1: "abc",
173+
}
174+
s2 := &S2{
175+
S1: s1,
176+
F2: "123",
177+
}
178+
str, err := MarshalToString(s2)
179+
should.Nil(err)
180+
should.Equal(`{"F2":"123"}`, str)
181+
}
182+
161183
func Test_recursive_struct(t *testing.T) {
162184
should := require.New(t)
163185
type TestObject struct {

0 commit comments

Comments
 (0)