mirror of https://github.com/goccy/go-json.git
Merge pull request #264 from goccy/feature/fix-indirect
Fix encoding of indirect layout structure
This commit is contained in:
commit
0a7e5d9001
|
@ -2004,3 +2004,32 @@ func TestInterfaceWithPointer(t *testing.T) {
|
||||||
}
|
}
|
||||||
assertEq(t, "interface{}", string(expected), string(actual))
|
assertEq(t, "interface{}", string(expected), string(actual))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIssue263(t *testing.T) {
|
||||||
|
type Foo struct {
|
||||||
|
A []string `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MyStruct struct {
|
||||||
|
Foo *Foo `json:"foo,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
s := MyStruct{
|
||||||
|
Foo: &Foo{
|
||||||
|
A: []string{"ls -lah"},
|
||||||
|
B: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
expected, err := stdjson.Marshal(s)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
actual, err := json.Marshal(s)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(expected, actual) {
|
||||||
|
t.Fatalf("expected:[%s] but got:[%s]", string(expected), string(actual))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1440,8 +1440,10 @@ func compileStruct(ctx *compileContext, isPtr bool) (*Opcode, error) {
|
||||||
// if parent is indirect type, set child indirect property to true
|
// if parent is indirect type, set child indirect property to true
|
||||||
valueCode.Flags |= IndirectFlags
|
valueCode.Flags |= IndirectFlags
|
||||||
} else {
|
} else {
|
||||||
// if parent is not indirect type and child have only one field, set child indirect property to false
|
// if parent is not indirect type, set child indirect property to false.
|
||||||
if i == 0 && valueCode.NextField != nil && valueCode.NextField.Op == OpStructEnd {
|
// but if parent's indirect is false and isPtr is true, then indirect must be true.
|
||||||
|
// Do this only if indirectConversion is enabled at the end of compileStruct.
|
||||||
|
if i == 0 {
|
||||||
valueCode.Flags &= ^IndirectFlags
|
valueCode.Flags &= ^IndirectFlags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1544,7 +1546,11 @@ func compileStruct(ctx *compileContext, isPtr bool) (*Opcode, error) {
|
||||||
delete(ctx.structTypeToCompiledCode, typeptr)
|
delete(ctx.structTypeToCompiledCode, typeptr)
|
||||||
|
|
||||||
if !disableIndirectConversion && (head.Flags&IndirectFlags == 0) && isPtr {
|
if !disableIndirectConversion && (head.Flags&IndirectFlags == 0) && isPtr {
|
||||||
head.Flags |= IndirectFlags
|
headCode := head
|
||||||
|
for strings.Contains(headCode.Op.String(), "Head") {
|
||||||
|
headCode.Flags |= IndirectFlags
|
||||||
|
headCode = headCode.Next
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, nil
|
return ret, nil
|
||||||
|
|
|
@ -631,6 +631,56 @@ func TestCoverInt(t *testing.T) {
|
||||||
}{A: -1}},
|
}{A: -1}},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// HeadIntNotRootMultiFields
|
||||||
|
{
|
||||||
|
name: "HeadIntNotRootMultiFields",
|
||||||
|
data: struct {
|
||||||
|
A struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}
|
||||||
|
}{A: struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}{A: -1, B: 1}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntNotRootOmitEmptyMultiFields",
|
||||||
|
data: struct {
|
||||||
|
A struct {
|
||||||
|
A int `json:"a,omitempty"`
|
||||||
|
B int `json:"b,omitempty"`
|
||||||
|
}
|
||||||
|
}{A: struct {
|
||||||
|
A int `json:"a,omitempty"`
|
||||||
|
B int `json:"b,omitempty"`
|
||||||
|
}{A: -1, B: 1}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntNotRootStringMultiFields",
|
||||||
|
data: struct {
|
||||||
|
A struct {
|
||||||
|
A int `json:"a,string"`
|
||||||
|
B int `json:"b,string"`
|
||||||
|
}
|
||||||
|
}{A: struct {
|
||||||
|
A int `json:"a,string"`
|
||||||
|
B int `json:"b,string"`
|
||||||
|
}{A: -1, B: 1}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HeadIntNotRootStringOmitEmptyMultiFields",
|
||||||
|
data: struct {
|
||||||
|
A struct {
|
||||||
|
A int `json:"a,string,omitempty"`
|
||||||
|
B int `json:"b,string,omitempty"`
|
||||||
|
}
|
||||||
|
}{A: struct {
|
||||||
|
A int `json:"a,string,omitempty"`
|
||||||
|
B int `json:"b,string,omitempty"`
|
||||||
|
}{A: -1, B: 1}},
|
||||||
|
},
|
||||||
|
|
||||||
// HeadIntPtrNotRoot
|
// HeadIntPtrNotRoot
|
||||||
{
|
{
|
||||||
name: "HeadIntPtrNotRoot",
|
name: "HeadIntPtrNotRoot",
|
||||||
|
@ -791,6 +841,56 @@ func TestCoverInt(t *testing.T) {
|
||||||
}{A: -1})},
|
}{A: -1})},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// PtrHeadIntNotRootMultiFields
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntNotRootMultiFields",
|
||||||
|
data: struct {
|
||||||
|
A *struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}
|
||||||
|
}{A: &(struct {
|
||||||
|
A int `json:"a"`
|
||||||
|
B int `json:"b"`
|
||||||
|
}{A: -1, B: 1})},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntNotRootOmitEmptyMultiFields",
|
||||||
|
data: struct {
|
||||||
|
A *struct {
|
||||||
|
A int `json:"a,omitempty"`
|
||||||
|
B int `json:"b,omitempty"`
|
||||||
|
}
|
||||||
|
}{A: &(struct {
|
||||||
|
A int `json:"a,omitempty"`
|
||||||
|
B int `json:"b,omitempty"`
|
||||||
|
}{A: -1, B: 1})},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntNotRootStringMultiFields",
|
||||||
|
data: struct {
|
||||||
|
A *struct {
|
||||||
|
A int `json:"a,string"`
|
||||||
|
B int `json:"b,string"`
|
||||||
|
}
|
||||||
|
}{A: &(struct {
|
||||||
|
A int `json:"a,string"`
|
||||||
|
B int `json:"b,string"`
|
||||||
|
}{A: -1, B: 1})},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PtrHeadIntNotRootStringOmitEmptyMultiFields",
|
||||||
|
data: struct {
|
||||||
|
A *struct {
|
||||||
|
A int `json:"a,string,omitempty"`
|
||||||
|
B int `json:"b,string,omitempty"`
|
||||||
|
}
|
||||||
|
}{A: &(struct {
|
||||||
|
A int `json:"a,string,omitempty"`
|
||||||
|
B int `json:"b,string,omitempty"`
|
||||||
|
}{A: -1, B: 1})},
|
||||||
|
},
|
||||||
|
|
||||||
// PtrHeadIntPtrNotRoot
|
// PtrHeadIntPtrNotRoot
|
||||||
{
|
{
|
||||||
name: "PtrHeadIntPtrNotRoot",
|
name: "PtrHeadIntPtrNotRoot",
|
||||||
|
|
Loading…
Reference in New Issue