Merge pull request #12 from goccy/feature/fix-field-after-omitempty

Fix encoding of struct field after omitempty field
This commit is contained in:
Masaaki Goshima 2020-08-08 19:00:47 +09:00 committed by GitHub
commit c359cc258f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 249 additions and 37 deletions

View File

@ -16,6 +16,9 @@ func (e *Encoder) compileHead(typ *rtype, withIndent bool) (*opcode, error) {
if typ.Kind() == reflect.Ptr { if typ.Kind() == reflect.Ptr {
typ = typ.Elem() typ = typ.Elem()
} }
if typ.Kind() == reflect.Map {
return e.compileMap(typ, false, withIndent)
}
return e.compile(typ, withIndent) return e.compile(typ, withIndent)
} }
@ -33,7 +36,7 @@ func (e *Encoder) compile(typ *rtype, withIndent bool) (*opcode, error) {
case reflect.Array: case reflect.Array:
return e.compileArray(typ, withIndent) return e.compileArray(typ, withIndent)
case reflect.Map: case reflect.Map:
return e.compileMap(typ, withIndent) return e.compileMap(typ, true, withIndent)
case reflect.Struct: case reflect.Struct:
return e.compileStruct(typ, withIndent) return e.compileStruct(typ, withIndent)
case reflect.Int: case reflect.Int:
@ -366,7 +369,7 @@ func mapiternext(it unsafe.Pointer)
//go:noescape //go:noescape
func maplen(m unsafe.Pointer) int func maplen(m unsafe.Pointer) int
func (e *Encoder) compileMap(typ *rtype, withIndent bool) (*opcode, error) { func (e *Encoder) compileMap(typ *rtype, withLoad, withIndent bool) (*opcode, error) {
// header => code => value => code => key => code => value => code => end // header => code => value => code => key => code => value => code => end
// ^ | // ^ |
// |_______________________| // |_______________________|
@ -387,13 +390,17 @@ func (e *Encoder) compileMap(typ *rtype, withIndent bool) (*opcode, error) {
e.indent-- e.indent--
header := newMapHeaderCode(typ, e.indent) header := newMapHeaderCode(typ, withLoad, e.indent)
header.key = key header.key = key
header.value = value header.value = value
end := newOpCode(opMapEnd, nil, e.indent, newEndOp(e.indent)) end := newOpCode(opMapEnd, nil, e.indent, newEndOp(e.indent))
if withIndent { if withIndent {
if header.op == opMapHead {
header.op = opMapHeadIndent header.op = opMapHeadIndent
} else {
header.op = opMapHeadLoadIndent
}
key.op = opMapKeyIndent key.op = opMapKeyIndent
value.op = opMapValueIndent value.op = opMapValueIndent
end.op = opMapEndIndent end.op = opMapEndIndent

View File

@ -47,11 +47,13 @@ const (
opArrayEndIndent opArrayEndIndent
opMapHead opMapHead
opMapHeadLoad
opMapKey opMapKey
opMapValue opMapValue
opMapEnd opMapEnd
opMapHeadIndent opMapHeadIndent
opMapHeadLoadIndent
opMapKeyIndent opMapKeyIndent
opMapValueIndent opMapValueIndent
opMapEndIndent opMapEndIndent
@ -327,8 +329,9 @@ func (t opType) String() string {
case opArrayEndIndent: case opArrayEndIndent:
return "ARRAY_END_INDENT" return "ARRAY_END_INDENT"
case opMapHead: case opMapHead:
return "MAP_HEAD" return "MAP_HEAD"
case opMapHeadLoad:
return "MAP_HEAD_LOAD"
case opMapKey: case opMapKey:
return "MAP_KEY" return "MAP_KEY"
case opMapValue: case opMapValue:
@ -338,6 +341,8 @@ func (t opType) String() string {
case opMapHeadIndent: case opMapHeadIndent:
return "MAP_HEAD_INDENT" return "MAP_HEAD_INDENT"
case opMapHeadLoadIndent:
return "MAP_HEAD_LOAD_INDENT"
case opMapKeyIndent: case opMapKeyIndent:
return "MAP_KEY_INDENT" return "MAP_KEY_INDENT"
case opMapValueIndent: case opMapValueIndent:
@ -919,10 +924,16 @@ func (c *mapValueCode) set(iter unsafe.Pointer) {
c.iter = iter c.iter = iter
} }
func newMapHeaderCode(typ *rtype, indent int) *mapHeaderCode { func newMapHeaderCode(typ *rtype, withLoad bool, indent int) *mapHeaderCode {
var op opType
if withLoad {
op = opMapHeadLoad
} else {
op = opMapHead
}
return &mapHeaderCode{ return &mapHeaderCode{
opcodeHeader: &opcodeHeader{ opcodeHeader: &opcodeHeader{
op: opMapHead, op: op,
typ: typ, typ: typ,
indent: indent, indent: indent,
}, },

View File

@ -129,6 +129,116 @@ func Test_Marshal(t *testing.T) {
bytes, err := json.Marshal(&v) bytes, err := json.Marshal(&v)
assertErr(t, err) assertErr(t, err)
assertEq(t, "struct", `{"t":1}`, string(bytes)) assertEq(t, "struct", `{"t":1}`, string(bytes))
t.Run("int", func(t *testing.T) {
var v struct {
A int `json:"a,omitempty"`
B int `json:"b"`
}
v.B = 1
bytes, err := json.Marshal(&v)
assertErr(t, err)
assertEq(t, "int", `{"b":1}`, string(bytes))
})
t.Run("int8", func(t *testing.T) {
var v struct {
A int `json:"a,omitempty"`
B int8 `json:"b"`
}
v.B = 1
bytes, err := json.Marshal(&v)
assertErr(t, err)
assertEq(t, "int8", `{"b":1}`, string(bytes))
})
t.Run("int16", func(t *testing.T) {
var v struct {
A int `json:"a,omitempty"`
B int16 `json:"b"`
}
v.B = 1
bytes, err := json.Marshal(&v)
assertErr(t, err)
assertEq(t, "int16", `{"b":1}`, string(bytes))
})
t.Run("int32", func(t *testing.T) {
var v struct {
A int `json:"a,omitempty"`
B int32 `json:"b"`
}
v.B = 1
bytes, err := json.Marshal(&v)
assertErr(t, err)
assertEq(t, "int32", `{"b":1}`, string(bytes))
})
t.Run("int64", func(t *testing.T) {
var v struct {
A int `json:"a,omitempty"`
B int64 `json:"b"`
}
v.B = 1
bytes, err := json.Marshal(&v)
assertErr(t, err)
assertEq(t, "int64", `{"b":1}`, string(bytes))
})
t.Run("string", func(t *testing.T) {
var v struct {
A int `json:"a,omitempty"`
B string `json:"b"`
}
v.B = "b"
bytes, err := json.Marshal(&v)
assertErr(t, err)
assertEq(t, "string", `{"b":"b"}`, string(bytes))
})
t.Run("float32", func(t *testing.T) {
var v struct {
A int `json:"a,omitempty"`
B float32 `json:"b"`
}
v.B = 1.1
bytes, err := json.Marshal(&v)
assertErr(t, err)
assertEq(t, "float32", `{"b":1.1}`, string(bytes))
})
t.Run("float64", func(t *testing.T) {
var v struct {
A int `json:"a,omitempty"`
B float64 `json:"b"`
}
v.B = 3.14
bytes, err := json.Marshal(&v)
assertErr(t, err)
assertEq(t, "float64", `{"b":3.14}`, string(bytes))
})
t.Run("slice", func(t *testing.T) {
var v struct {
A int `json:"a,omitempty"`
B []int `json:"b"`
}
v.B = []int{1, 2, 3}
bytes, err := json.Marshal(&v)
assertErr(t, err)
assertEq(t, "slice", `{"b":[1,2,3]}`, string(bytes))
})
t.Run("array", func(t *testing.T) {
var v struct {
A int `json:"a,omitempty"`
B [2]int `json:"b"`
}
v.B = [2]int{1, 2}
bytes, err := json.Marshal(&v)
assertErr(t, err)
assertEq(t, "array", `{"b":[1,2]}`, string(bytes))
})
t.Run("map", func(t *testing.T) {
v := new(struct {
A int `json:"a,omitempty"`
B map[string]interface{} `json:"b"`
})
v.B = map[string]interface{}{"c": 1}
bytes, err := json.Marshal(v)
assertErr(t, err)
assertEq(t, "array", `{"b":{"c":1}}`, string(bytes))
})
}) })
t.Run("head_omitempty", func(t *testing.T) { t.Run("head_omitempty", func(t *testing.T) {
type T struct { type T struct {

View File

@ -264,6 +264,30 @@ func (e *Encoder) run(code *opcode) error {
code = mapHeadCode.end.next code = mapHeadCode.end.next
} }
} }
case opMapHeadLoad:
ptr := code.ptr
mapHeadCode := code.toMapHeadCode()
if ptr == 0 {
e.encodeNull()
code = mapHeadCode.end.next
} else {
// load pointer
ptr = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(ptr)))
e.encodeByte('{')
mlen := maplen(unsafe.Pointer(ptr))
if mlen > 0 {
iter := mapiterinit(code.typ, unsafe.Pointer(ptr))
mapHeadCode.key.set(mlen, iter)
mapHeadCode.value.set(iter)
key := mapiterkey(iter)
code.next.ptr = uintptr(key)
code = code.next
} else {
e.encodeByte('}')
code = mapHeadCode.end.next
}
}
case opMapKey: case opMapKey:
c := code.toMapKeyCode() c := code.toMapKeyCode()
c.idx++ c.idx++
@ -1681,91 +1705,117 @@ func (e *Encoder) run(code *opcode) error {
field.nextField.ptr = field.ptr field.nextField.ptr = field.ptr
} }
case opStructField: case opStructField:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
e.encodeBytes(c.key) e.encodeBytes(c.key)
code = code.next code = code.next
code.ptr = c.ptr + c.offset code.ptr = c.ptr + c.offset
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldInt: case opStructFieldInt:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeInt(e.ptrToInt(c.ptr + c.offset)) e.encodeInt(e.ptrToInt(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldInt8: case opStructFieldInt8:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeInt8(e.ptrToInt8(c.ptr + c.offset)) e.encodeInt8(e.ptrToInt8(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldInt16: case opStructFieldInt16:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeInt16(e.ptrToInt16(c.ptr + c.offset)) e.encodeInt16(e.ptrToInt16(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldInt32: case opStructFieldInt32:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeInt32(e.ptrToInt32(c.ptr + c.offset)) e.encodeInt32(e.ptrToInt32(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldInt64: case opStructFieldInt64:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeInt64(e.ptrToInt64(c.ptr + c.offset)) e.encodeInt64(e.ptrToInt64(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldUint: case opStructFieldUint:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeUint(e.ptrToUint(c.ptr + c.offset)) e.encodeUint(e.ptrToUint(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldUint8: case opStructFieldUint8:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeUint8(e.ptrToUint8(c.ptr + c.offset)) e.encodeUint8(e.ptrToUint8(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldUint16: case opStructFieldUint16:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeUint16(e.ptrToUint16(c.ptr + c.offset)) e.encodeUint16(e.ptrToUint16(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldUint32: case opStructFieldUint32:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeUint32(e.ptrToUint32(c.ptr + c.offset)) e.encodeUint32(e.ptrToUint32(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldUint64: case opStructFieldUint64:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeUint64(e.ptrToUint64(c.ptr + c.offset)) e.encodeUint64(e.ptrToUint64(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldFloat32: case opStructFieldFloat32:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeFloat32(e.ptrToFloat32(c.ptr + c.offset)) e.encodeFloat32(e.ptrToFloat32(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldFloat64: case opStructFieldFloat64:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
@ -1779,14 +1829,18 @@ func (e *Encoder) run(code *opcode) error {
e.encodeFloat64(v) e.encodeFloat64(v)
code = code.next code = code.next
case opStructFieldString: case opStructFieldString:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeString(e.ptrToString(c.ptr + c.offset)) e.encodeString(e.ptrToString(c.ptr + c.offset))
code = code.next code = code.next
case opStructFieldBool: case opStructFieldBool:
if e.buf[len(e.buf)-1] != '{' {
e.encodeByte(',') e.encodeByte(',')
}
c := code.toStructFieldCode() c := code.toStructFieldCode()
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
e.encodeBytes(c.key) e.encodeBytes(c.key)
@ -1795,7 +1849,9 @@ func (e *Encoder) run(code *opcode) error {
case opStructFieldIndent: case opStructFieldIndent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1804,7 +1860,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldIntIndent: case opStructFieldIntIndent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1813,7 +1871,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldInt8Indent: case opStructFieldInt8Indent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1822,7 +1882,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldInt16Indent: case opStructFieldInt16Indent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1831,7 +1893,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldInt32Indent: case opStructFieldInt32Indent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1840,7 +1904,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldInt64Indent: case opStructFieldInt64Indent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1849,7 +1915,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldUintIndent: case opStructFieldUintIndent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1858,7 +1926,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldUint8Indent: case opStructFieldUint8Indent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1867,7 +1937,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldUint16Indent: case opStructFieldUint16Indent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1876,7 +1948,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldUint32Indent: case opStructFieldUint32Indent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1885,7 +1959,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldUint64Indent: case opStructFieldUint64Indent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1894,7 +1970,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldFloat32Indent: case opStructFieldFloat32Indent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1903,7 +1981,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldFloat64Indent: case opStructFieldFloat64Indent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1919,7 +1999,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldStringIndent: case opStructFieldStringIndent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')
@ -1928,7 +2010,9 @@ func (e *Encoder) run(code *opcode) error {
c.nextField.ptr = c.ptr c.nextField.ptr = c.ptr
case opStructFieldBoolIndent: case opStructFieldBoolIndent:
c := code.toStructFieldCode() c := code.toStructFieldCode()
if e.buf[len(e.buf)-2] != '{' {
e.encodeBytes([]byte{',', '\n'}) e.encodeBytes([]byte{',', '\n'})
}
e.encodeIndent(c.indent) e.encodeIndent(c.indent)
e.encodeBytes(c.key) e.encodeBytes(c.key)
e.encodeByte(' ') e.encodeByte(' ')