Fix encoding of omitempty feature for the slice or interface type

This commit is contained in:
Masaaki Goshima 2021-04-10 16:25:45 +09:00
parent 8bc5727ba4
commit 69e40becbf
7 changed files with 57 additions and 11 deletions

View File

@ -1806,6 +1806,52 @@ func TestIssue104(t *testing.T) {
}
}
func TestIssue179(t *testing.T) {
data := `
{
"t": {
"t1": false,
"t2": 0,
"t3": "",
"t4": [],
"t5": null,
"t6": null
}
}`
type T struct {
X struct {
T1 bool `json:"t1,omitempty"`
T2 float64 `json:"t2,omitempty"`
T3 string `json:"t3,omitempty"`
T4 []string `json:"t4,omitempty"`
T5 *struct{} `json:"t5,omitempty"`
T6 interface{} `json:"t6,omitempty"`
} `json:"x"`
}
var v T
if err := stdjson.Unmarshal([]byte(data), &v); err != nil {
t.Fatal(err)
}
var v2 T
if err := json.Unmarshal([]byte(data), &v2); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(v, v2) {
t.Fatalf("failed to decode: expected %v got %v", v, v2)
}
b1, err := stdjson.Marshal(v)
if err != nil {
t.Fatal(err)
}
b2, err := json.Marshal(v2)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(b1, b2) {
t.Fatalf("failed to equal encoded result: expected %q but got %q", b1, b2)
}
}
func TestIssue180(t *testing.T) {
v := struct {
T struct {

View File

@ -1439,7 +1439,7 @@ func compileStruct(ctx *compileContext, isPtr bool) (*Opcode, error) {
Indirect: indirect,
Nilcheck: nilcheck,
AddrForMarshaler: addrForMarshaler,
IsNextOpPtrType: strings.Contains(valueCode.Op.String(), "Ptr"),
IsNextOpPtrType: strings.Contains(valueCode.Op.String(), "Ptr") || valueCode.Op == OpInterface,
IsNilableType: isNilableType,
}
if fieldIdx == 0 {

View File

@ -2451,7 +2451,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
}
p += code.Offset
slice := ptrToSlice(p)
if slice.Data == nil {
if slice.Len == 0 {
code = code.NextField
} else {
b = append(b, code.Key...)
@ -3780,7 +3780,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
p := load(ctxptr, code.HeadIdx)
p += code.Offset
slice := ptrToSlice(p)
if slice.Data == nil {
if slice.Len == 0 {
code = code.NextField
} else {
b = append(b, code.Key...)

View File

@ -2464,7 +2464,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
}
p += code.Offset
slice := ptrToSlice(p)
if slice.Data == nil {
if slice.Len == 0 {
code = code.NextField
} else {
b = append(b, code.Key...)
@ -3793,7 +3793,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
p := load(ctxptr, code.HeadIdx)
p += code.Offset
slice := ptrToSlice(p)
if slice.Data == nil {
if slice.Len == 0 {
code = code.NextField
} else {
b = append(b, code.Key...)

View File

@ -2451,7 +2451,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
}
p += code.Offset
slice := ptrToSlice(p)
if slice.Data == nil {
if slice.Len == 0 {
code = code.NextField
} else {
b = append(b, code.EscapedKey...)
@ -3780,7 +3780,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
p := load(ctxptr, code.HeadIdx)
p += code.Offset
slice := ptrToSlice(p)
if slice.Data == nil {
if slice.Len == 0 {
code = code.NextField
} else {
b = append(b, code.EscapedKey...)

View File

@ -2576,7 +2576,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
}
p += code.Offset
slice := ptrToSlice(p)
if slice.Data == nil {
if slice.Len == 0 {
code = code.NextField
} else {
b = appendIndent(ctx, b, code.Indent+1)
@ -4059,7 +4059,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
p := load(ctxptr, code.HeadIdx)
p += code.Offset
slice := ptrToSlice(p)
if slice.Data == nil {
if slice.Len == 0 {
code = code.NextField
} else {
b = appendIndent(ctx, b, code.Indent)

View File

@ -2576,7 +2576,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
}
p += code.Offset
slice := ptrToSlice(p)
if slice.Data == nil {
if slice.Len == 0 {
code = code.NextField
} else {
b = appendIndent(ctx, b, code.Indent+1)
@ -4059,7 +4059,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
p := load(ctxptr, code.HeadIdx)
p += code.Offset
slice := ptrToSlice(p)
if slice.Data == nil {
if slice.Len == 0 {
code = code.NextField
} else {
b = appendIndent(ctx, b, code.Indent)