mirror of
https://github.com/json-iterator/go.git
synced 2024-11-27 08:30:57 +02:00
#97 omit empty behavior should follow the original type
This commit is contained in:
parent
d0c5988985
commit
f2c50ef73b
@ -32,6 +32,10 @@ type ValEncoder interface {
|
||||
EncodeInterface(val interface{}, stream *Stream)
|
||||
}
|
||||
|
||||
type checkIsEmpty interface {
|
||||
IsEmpty(ptr unsafe.Pointer) bool
|
||||
}
|
||||
|
||||
func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) {
|
||||
e := (*emptyInterface)(unsafe.Pointer(&val))
|
||||
if e.word == nil {
|
||||
@ -424,7 +428,6 @@ func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
|
||||
}
|
||||
|
||||
func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
|
||||
typeName := typ.String()
|
||||
if typ == jsonRawMessageType {
|
||||
return &jsonRawMessageCodec{}, nil
|
||||
}
|
||||
@ -438,17 +441,31 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error
|
||||
return &base64Codec{typ}, nil
|
||||
}
|
||||
if typ.Implements(marshalerType) {
|
||||
checkIsEmpty, err := createEncoderOfSimpleType(cfg, typ)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
templateInterface := reflect.New(typ).Elem().Interface()
|
||||
var encoder ValEncoder = &marshalerEncoder{extractInterface(templateInterface)}
|
||||
if typ.Kind() != reflect.Struct {
|
||||
var encoder ValEncoder = &marshalerEncoder{
|
||||
templateInterface: extractInterface(templateInterface),
|
||||
checkIsEmpty: checkIsEmpty,
|
||||
}
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
encoder = &optionalEncoder{encoder}
|
||||
}
|
||||
return encoder, nil
|
||||
}
|
||||
if typ.Implements(textMarshalerType) {
|
||||
checkIsEmpty, err := createEncoderOfSimpleType(cfg, typ)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
templateInterface := reflect.New(typ).Elem().Interface()
|
||||
var encoder ValEncoder = &textMarshalerEncoder{extractInterface(templateInterface)}
|
||||
if typ.Kind() != reflect.Struct {
|
||||
var encoder ValEncoder = &textMarshalerEncoder{
|
||||
templateInterface: extractInterface(templateInterface),
|
||||
checkIsEmpty: checkIsEmpty,
|
||||
}
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
encoder = &optionalEncoder{encoder}
|
||||
}
|
||||
return encoder, nil
|
||||
@ -456,6 +473,11 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error
|
||||
if typ.Implements(anyType) {
|
||||
return &anyCodec{}, nil
|
||||
}
|
||||
return createEncoderOfSimpleType(cfg, typ)
|
||||
}
|
||||
|
||||
func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
|
||||
typeName := typ.String()
|
||||
kind := typ.Kind()
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
|
@ -419,7 +419,7 @@ func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
}
|
||||
encoding := base64.StdEncoding
|
||||
src := iter.SkipAndReturnBytes()
|
||||
src = src[1 : len(src)-1]
|
||||
src = src[1: len(src)-1]
|
||||
decodedLen := encoding.DecodedLen(len(src))
|
||||
dst := make([]byte, decodedLen)
|
||||
len, err := encoding.Decode(dst, src)
|
||||
@ -544,6 +544,7 @@ func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||
|
||||
type marshalerEncoder struct {
|
||||
templateInterface emptyInterface
|
||||
checkIsEmpty checkIsEmpty
|
||||
}
|
||||
|
||||
func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||
@ -563,20 +564,12 @@ func (encoder *marshalerEncoder) EncodeInterface(val interface{}, stream *Stream
|
||||
}
|
||||
|
||||
func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||
templateInterface := encoder.templateInterface
|
||||
templateInterface.word = ptr
|
||||
realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
|
||||
marshaler := (*realInterface).(json.Marshaler)
|
||||
bytes, err := marshaler.MarshalJSON()
|
||||
if err != nil {
|
||||
return true
|
||||
} else {
|
||||
return len(bytes) > 0
|
||||
}
|
||||
return encoder.checkIsEmpty.IsEmpty(ptr)
|
||||
}
|
||||
|
||||
type textMarshalerEncoder struct {
|
||||
templateInterface emptyInterface
|
||||
checkIsEmpty checkIsEmpty
|
||||
}
|
||||
|
||||
func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||
@ -597,16 +590,7 @@ func (encoder *textMarshalerEncoder) EncodeInterface(val interface{}, stream *St
|
||||
}
|
||||
|
||||
func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||
templateInterface := encoder.templateInterface
|
||||
templateInterface.word = ptr
|
||||
realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
|
||||
marshaler := (*realInterface).(encoding.TextMarshaler)
|
||||
bytes, err := marshaler.MarshalText()
|
||||
if err != nil {
|
||||
return true
|
||||
} else {
|
||||
return len(bytes) > 0
|
||||
}
|
||||
return encoder.checkIsEmpty.IsEmpty(ptr)
|
||||
}
|
||||
|
||||
type unmarshalerDecoder struct {
|
||||
|
Loading…
Reference in New Issue
Block a user