mirror of
https://github.com/json-iterator/go.git
synced 2025-03-20 20:54:55 +02:00
#58 string mode support both encoding and decoding
This commit is contained in:
parent
b31b1301e2
commit
3d5f6d3a4a
@ -427,14 +427,14 @@ func (encoder *base64Codec) isEmpty(ptr unsafe.Pointer) bool {
|
||||
return len(*((*[]byte)(ptr))) == 0
|
||||
}
|
||||
|
||||
type stringNumberDecoder struct {
|
||||
type stringModeDecoder struct {
|
||||
elemDecoder Decoder
|
||||
}
|
||||
|
||||
func (decoder *stringNumberDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
func (decoder *stringModeDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
c := iter.nextToken()
|
||||
if c != '"' {
|
||||
iter.reportError("stringNumberDecoder", `expect "`)
|
||||
iter.reportError("stringModeDecoder", `expect "`)
|
||||
return
|
||||
}
|
||||
decoder.elemDecoder.decode(ptr, iter)
|
||||
@ -443,11 +443,29 @@ func (decoder *stringNumberDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
}
|
||||
c = iter.readByte()
|
||||
if c != '"' {
|
||||
iter.reportError("stringNumberDecoder", `expect "`)
|
||||
iter.reportError("stringModeDecoder", `expect "`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
type stringModeEncoder struct {
|
||||
elemEncoder Encoder
|
||||
}
|
||||
|
||||
func (encoder *stringModeEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
|
||||
stream.writeByte('"')
|
||||
encoder.elemEncoder.encode(ptr, stream)
|
||||
stream.writeByte('"')
|
||||
}
|
||||
|
||||
func (encoder *stringModeEncoder) encodeInterface(val interface{}, stream *Stream) {
|
||||
writeToStream(val, stream, encoder)
|
||||
}
|
||||
|
||||
func (encoder *stringModeEncoder) isEmpty(ptr unsafe.Pointer) bool {
|
||||
return encoder.elemEncoder.isEmpty(ptr)
|
||||
}
|
||||
|
||||
type marshalerEncoder struct {
|
||||
templateInterface emptyInterface
|
||||
}
|
||||
|
@ -37,9 +37,12 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (Encoder, error) {
|
||||
// if fieldNames set by extension, use theirs, otherwise try tags
|
||||
fieldNames := calcFieldNames(field.Name, tagParts[0], extensionProvidedFieldNames)
|
||||
omitempty := false
|
||||
for _, tagPart := range tagParts {
|
||||
stringMode := false
|
||||
for _, tagPart := range tagParts[1:] {
|
||||
if tagPart == "omitempty" {
|
||||
omitempty = true
|
||||
} else if tagPart == "string" {
|
||||
stringMode = true
|
||||
}
|
||||
}
|
||||
encoder := fieldEncoders[fieldEncoderKey]
|
||||
@ -54,6 +57,9 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (Encoder, error) {
|
||||
encoder = &optionalEncoder{encoder}
|
||||
}
|
||||
}
|
||||
if stringMode {
|
||||
encoder = &stringModeEncoder{encoder}
|
||||
}
|
||||
for _, fieldName := range fieldNames {
|
||||
fields[fieldName] = &structFieldEncoder{field, fieldName, encoder, omitempty}
|
||||
}
|
||||
@ -114,8 +120,10 @@ func decoderOfStruct(cfg *frozenConfig, typ reflect.Type) (Decoder, error) {
|
||||
return prefix(fmt.Sprintf("{%s}", field.Name)).addToDecoder(decoder, err)
|
||||
}
|
||||
}
|
||||
if len(tagParts) > 1 && tagParts[1] == "string" {
|
||||
decoder = &stringNumberDecoder{decoder}
|
||||
for _, tagPart := range tagParts[1:] {
|
||||
if tagPart == "string" {
|
||||
decoder = &stringModeDecoder{decoder}
|
||||
}
|
||||
}
|
||||
for _, fieldName := range fieldNames {
|
||||
fields[fieldName] = &structFieldDecoder{&field, decoder}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"github.com/json-iterator/go/require"
|
||||
"testing"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func Test_true(t *testing.T) {
|
||||
@ -47,3 +48,40 @@ func Test_write_val_bool(t *testing.T) {
|
||||
should.Nil(stream.Error)
|
||||
should.Equal("true", buf.String())
|
||||
}
|
||||
|
||||
func Test_encode_string_bool(t *testing.T) {
|
||||
type TestObject struct {
|
||||
Field bool `json:",omitempty,string"`
|
||||
}
|
||||
should := require.New(t)
|
||||
output, err := json.Marshal(TestObject{true})
|
||||
should.Nil(err)
|
||||
should.Equal(`{"Field":"true"}`, string(output))
|
||||
output, err = Marshal(TestObject{true})
|
||||
should.Nil(err)
|
||||
should.Equal(`{"Field":"true"}`, string(output))
|
||||
}
|
||||
|
||||
func Test_decode_string_bool(t *testing.T) {
|
||||
type TestObject struct {
|
||||
Field bool `json:",omitempty,string"`
|
||||
}
|
||||
should := require.New(t)
|
||||
obj := TestObject{}
|
||||
err := json.Unmarshal([]byte(`{"Field":"true"}`), &obj)
|
||||
should.Nil(err)
|
||||
should.True(obj.Field)
|
||||
|
||||
obj = TestObject{}
|
||||
err = json.Unmarshal([]byte(`{"Field":true}`), &obj)
|
||||
should.NotNil(err)
|
||||
|
||||
obj = TestObject{}
|
||||
err = Unmarshal([]byte(`{"Field":"true"}`), &obj)
|
||||
should.Nil(err)
|
||||
should.True(obj.Field)
|
||||
|
||||
obj = TestObject{}
|
||||
err = Unmarshal([]byte(`{"Field":true}`), &obj)
|
||||
should.NotNil(err)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user