mirror of
https://github.com/json-iterator/go.git
synced 2025-04-23 11:37:32 +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)
|
EncodeInterface(val interface{}, stream *Stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type checkIsEmpty interface {
|
||||||
|
IsEmpty(ptr unsafe.Pointer) bool
|
||||||
|
}
|
||||||
|
|
||||||
func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) {
|
func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) {
|
||||||
e := (*emptyInterface)(unsafe.Pointer(&val))
|
e := (*emptyInterface)(unsafe.Pointer(&val))
|
||||||
if e.word == nil {
|
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) {
|
func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
|
||||||
typeName := typ.String()
|
|
||||||
if typ == jsonRawMessageType {
|
if typ == jsonRawMessageType {
|
||||||
return &jsonRawMessageCodec{}, nil
|
return &jsonRawMessageCodec{}, nil
|
||||||
}
|
}
|
||||||
@ -438,17 +441,31 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error
|
|||||||
return &base64Codec{typ}, nil
|
return &base64Codec{typ}, nil
|
||||||
}
|
}
|
||||||
if typ.Implements(marshalerType) {
|
if typ.Implements(marshalerType) {
|
||||||
|
checkIsEmpty, err := createEncoderOfSimpleType(cfg, typ)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
templateInterface := reflect.New(typ).Elem().Interface()
|
templateInterface := reflect.New(typ).Elem().Interface()
|
||||||
var encoder ValEncoder = &marshalerEncoder{extractInterface(templateInterface)}
|
var encoder ValEncoder = &marshalerEncoder{
|
||||||
if typ.Kind() != reflect.Struct {
|
templateInterface: extractInterface(templateInterface),
|
||||||
|
checkIsEmpty: checkIsEmpty,
|
||||||
|
}
|
||||||
|
if typ.Kind() == reflect.Ptr {
|
||||||
encoder = &optionalEncoder{encoder}
|
encoder = &optionalEncoder{encoder}
|
||||||
}
|
}
|
||||||
return encoder, nil
|
return encoder, nil
|
||||||
}
|
}
|
||||||
if typ.Implements(textMarshalerType) {
|
if typ.Implements(textMarshalerType) {
|
||||||
|
checkIsEmpty, err := createEncoderOfSimpleType(cfg, typ)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
templateInterface := reflect.New(typ).Elem().Interface()
|
templateInterface := reflect.New(typ).Elem().Interface()
|
||||||
var encoder ValEncoder = &textMarshalerEncoder{extractInterface(templateInterface)}
|
var encoder ValEncoder = &textMarshalerEncoder{
|
||||||
if typ.Kind() != reflect.Struct {
|
templateInterface: extractInterface(templateInterface),
|
||||||
|
checkIsEmpty: checkIsEmpty,
|
||||||
|
}
|
||||||
|
if typ.Kind() == reflect.Ptr {
|
||||||
encoder = &optionalEncoder{encoder}
|
encoder = &optionalEncoder{encoder}
|
||||||
}
|
}
|
||||||
return encoder, nil
|
return encoder, nil
|
||||||
@ -456,6 +473,11 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error
|
|||||||
if typ.Implements(anyType) {
|
if typ.Implements(anyType) {
|
||||||
return &anyCodec{}, nil
|
return &anyCodec{}, nil
|
||||||
}
|
}
|
||||||
|
return createEncoderOfSimpleType(cfg, typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
|
||||||
|
typeName := typ.String()
|
||||||
kind := typ.Kind()
|
kind := typ.Kind()
|
||||||
switch kind {
|
switch kind {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
|
@ -544,6 +544,7 @@ func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|||||||
|
|
||||||
type marshalerEncoder struct {
|
type marshalerEncoder struct {
|
||||||
templateInterface emptyInterface
|
templateInterface emptyInterface
|
||||||
|
checkIsEmpty checkIsEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
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 {
|
func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
templateInterface := encoder.templateInterface
|
return encoder.checkIsEmpty.IsEmpty(ptr)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type textMarshalerEncoder struct {
|
type textMarshalerEncoder struct {
|
||||||
templateInterface emptyInterface
|
templateInterface emptyInterface
|
||||||
|
checkIsEmpty checkIsEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
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 {
|
func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
templateInterface := encoder.templateInterface
|
return encoder.checkIsEmpty.IsEmpty(ptr)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type unmarshalerDecoder struct {
|
type unmarshalerDecoder struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user