forked from mirror/go-json
Support string tag operation
This commit is contained in:
parent
8f7cb46c5d
commit
22f3bba9a8
|
@ -433,10 +433,13 @@ func (e *Encoder) typeToFieldType(op opType) opType {
|
||||||
return opStructField
|
return opStructField
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) optimizeStructHeader(op opType, isOmitEmpty, withIndent bool) opType {
|
func (e *Encoder) optimizeStructHeader(op opType, tag *structTag, withIndent bool) opType {
|
||||||
headType := e.typeToHeaderType(op)
|
headType := e.typeToHeaderType(op)
|
||||||
if isOmitEmpty {
|
switch {
|
||||||
|
case tag.isOmitEmpty:
|
||||||
headType = headType.headToOmitEmptyHead()
|
headType = headType.headToOmitEmptyHead()
|
||||||
|
case tag.isString:
|
||||||
|
headType = headType.headToStringTagHead()
|
||||||
}
|
}
|
||||||
if withIndent {
|
if withIndent {
|
||||||
return headType.toIndent()
|
return headType.toIndent()
|
||||||
|
@ -444,10 +447,13 @@ func (e *Encoder) optimizeStructHeader(op opType, isOmitEmpty, withIndent bool)
|
||||||
return headType
|
return headType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) optimizeStructField(op opType, isOmitEmpty, withIndent bool) opType {
|
func (e *Encoder) optimizeStructField(op opType, tag *structTag, withIndent bool) opType {
|
||||||
fieldType := e.typeToFieldType(op)
|
fieldType := e.typeToFieldType(op)
|
||||||
if isOmitEmpty {
|
switch {
|
||||||
|
case tag.isOmitEmpty:
|
||||||
fieldType = fieldType.fieldToOmitEmptyField()
|
fieldType = fieldType.fieldToOmitEmptyField()
|
||||||
|
case tag.isString:
|
||||||
|
fieldType = fieldType.fieldToStringTagField()
|
||||||
}
|
}
|
||||||
if withIndent {
|
if withIndent {
|
||||||
return fieldType.toIndent()
|
return fieldType.toIndent()
|
||||||
|
@ -481,7 +487,13 @@ func (e *Encoder) compiledCode(typ *rtype, withIndent bool) *opcode {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) keyNameAndOmitEmptyFromField(field reflect.StructField) (string, bool) {
|
type structTag struct {
|
||||||
|
key string
|
||||||
|
isOmitEmpty bool
|
||||||
|
isString bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) structTagFromField(field reflect.StructField) *structTag {
|
||||||
keyName := field.Name
|
keyName := field.Name
|
||||||
tag := e.getTag(field)
|
tag := e.getTag(field)
|
||||||
opts := strings.Split(tag, ",")
|
opts := strings.Split(tag, ",")
|
||||||
|
@ -490,16 +502,17 @@ func (e *Encoder) keyNameAndOmitEmptyFromField(field reflect.StructField) (strin
|
||||||
keyName = opts[0]
|
keyName = opts[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isOmitEmpty := false
|
st := &structTag{key: keyName}
|
||||||
if len(opts) > 1 {
|
if len(opts) > 1 {
|
||||||
isOmitEmpty = opts[1] == "omitempty"
|
st.isOmitEmpty = opts[1] == "omitempty"
|
||||||
|
st.isString = opts[1] == "string"
|
||||||
}
|
}
|
||||||
return keyName, isOmitEmpty
|
return st
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) structHeader(fieldCode *structFieldCode, valueCode *opcode, isOmitEmpty, withIndent bool) *opcode {
|
func (e *Encoder) structHeader(fieldCode *structFieldCode, valueCode *opcode, tag *structTag, withIndent bool) *opcode {
|
||||||
fieldCode.indent--
|
fieldCode.indent--
|
||||||
op := e.optimizeStructHeader(valueCode.op, isOmitEmpty, withIndent)
|
op := e.optimizeStructHeader(valueCode.op, tag, withIndent)
|
||||||
fieldCode.op = op
|
fieldCode.op = op
|
||||||
switch op {
|
switch op {
|
||||||
case opStructFieldHead,
|
case opStructFieldHead,
|
||||||
|
@ -511,9 +524,9 @@ func (e *Encoder) structHeader(fieldCode *structFieldCode, valueCode *opcode, is
|
||||||
return (*opcode)(unsafe.Pointer(fieldCode))
|
return (*opcode)(unsafe.Pointer(fieldCode))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) structField(fieldCode *structFieldCode, valueCode *opcode, isOmitEmpty, withIndent bool) *opcode {
|
func (e *Encoder) structField(fieldCode *structFieldCode, valueCode *opcode, tag *structTag, withIndent bool) *opcode {
|
||||||
code := (*opcode)(unsafe.Pointer(fieldCode))
|
code := (*opcode)(unsafe.Pointer(fieldCode))
|
||||||
op := e.optimizeStructField(valueCode.op, isOmitEmpty, withIndent)
|
op := e.optimizeStructField(valueCode.op, tag, withIndent)
|
||||||
fieldCode.op = op
|
fieldCode.op = op
|
||||||
switch op {
|
switch op {
|
||||||
case opStructField,
|
case opStructField,
|
||||||
|
@ -551,7 +564,7 @@ func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opco
|
||||||
if e.isIgnoredStructField(field) {
|
if e.isIgnoredStructField(field) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
keyName, isOmitEmpty := e.keyNameAndOmitEmptyFromField(field)
|
tag := e.structTagFromField(field)
|
||||||
fieldType := type2rtype(field.Type)
|
fieldType := type2rtype(field.Type)
|
||||||
if isPtr && i == 0 {
|
if isPtr && i == 0 {
|
||||||
// head field of pointer structure at top level
|
// head field of pointer structure at top level
|
||||||
|
@ -579,7 +592,7 @@ func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opco
|
||||||
f = f.nextField.toStructFieldCode()
|
f = f.nextField.toStructFieldCode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key := fmt.Sprintf(`"%s":`, keyName)
|
key := fmt.Sprintf(`"%s":`, tag.key)
|
||||||
fieldCode := &structFieldCode{
|
fieldCode := &structFieldCode{
|
||||||
opcodeHeader: &opcodeHeader{
|
opcodeHeader: &opcodeHeader{
|
||||||
typ: valueCode.typ,
|
typ: valueCode.typ,
|
||||||
|
@ -591,13 +604,13 @@ func (e *Encoder) compileStruct(typ *rtype, isPtr, root, withIndent bool) (*opco
|
||||||
offset: field.Offset,
|
offset: field.Offset,
|
||||||
}
|
}
|
||||||
if fieldIdx == 0 {
|
if fieldIdx == 0 {
|
||||||
code = e.structHeader(fieldCode, valueCode, isOmitEmpty, withIndent)
|
code = e.structHeader(fieldCode, valueCode, tag, withIndent)
|
||||||
head = fieldCode
|
head = fieldCode
|
||||||
prevField = fieldCode
|
prevField = fieldCode
|
||||||
} else {
|
} else {
|
||||||
fcode := (*opcode)(unsafe.Pointer(fieldCode))
|
fcode := (*opcode)(unsafe.Pointer(fieldCode))
|
||||||
code.next = fcode
|
code.next = fcode
|
||||||
code = e.structField(fieldCode, valueCode, isOmitEmpty, withIndent)
|
code = e.structField(fieldCode, valueCode, tag, withIndent)
|
||||||
prevField.nextField = fcode
|
prevField.nextField = fcode
|
||||||
prevField = fieldCode
|
prevField = fieldCode
|
||||||
}
|
}
|
||||||
|
|
1520
encode_vm.go
1520
encode_vm.go
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue