diff --git a/feature_reflect.go b/feature_reflect.go index 94d8c29..8458d30 100644 --- a/feature_reflect.go +++ b/feature_reflect.go @@ -333,56 +333,10 @@ func createEncoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) Val if typ.AssignableTo(jsoniterNumberType) { return &jsoniterNumberCodec{} } - if typ == marshalerType { - checkIsEmpty := createCheckIsEmpty(cfg, typ) - var encoder ValEncoder = &directMarshalerEncoder{ - checkIsEmpty: checkIsEmpty, - } + encoder := createEncoderOfMarshaler(cfg, prefix, typ) + if encoder != nil { return encoder } - if typ.Implements(marshalerType) { - checkIsEmpty := createCheckIsEmpty(cfg, typ) - var encoder ValEncoder = &marshalerEncoder{ - valType: reflect2.Type2(typ), - checkIsEmpty: checkIsEmpty, - } - return encoder - } - ptrType := reflect.PtrTo(typ) - if ptrType.Implements(marshalerType) { - checkIsEmpty := createCheckIsEmpty(cfg, ptrType) - var encoder ValEncoder = &marshalerEncoder{ - valType: reflect2.Type2(ptrType), - checkIsEmpty: checkIsEmpty, - } - return &referenceEncoder{encoder} - } - if typ == textMarshalerType { - checkIsEmpty := createCheckIsEmpty(cfg, typ) - var encoder ValEncoder = &directTextMarshalerEncoder{ - checkIsEmpty: checkIsEmpty, - stringEncoder: cfg.EncoderOf(reflect.TypeOf("")), - } - return encoder - } - if typ.Implements(textMarshalerType) { - checkIsEmpty := createCheckIsEmpty(cfg, typ) - var encoder ValEncoder = &textMarshalerEncoder{ - valType: reflect2.Type2(typ), - stringEncoder: cfg.EncoderOf(reflect.TypeOf("")), - checkIsEmpty: checkIsEmpty, - } - return encoder - } - if typ.Kind() == reflect.Map && ptrType.Implements(textMarshalerType) { - checkIsEmpty := createCheckIsEmpty(cfg, ptrType) - var encoder ValEncoder = &textMarshalerEncoder{ - valType: reflect2.Type2(ptrType), - stringEncoder: cfg.EncoderOf(reflect.TypeOf("")), - checkIsEmpty: checkIsEmpty, - } - return &referenceEncoder{encoder} - } if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { return &base64Codec{} } diff --git a/feature_reflect_marshaler.go b/feature_reflect_marshaler.go index 56c93d3..b3a1dcf 100644 --- a/feature_reflect_marshaler.go +++ b/feature_reflect_marshaler.go @@ -5,8 +5,64 @@ import ( "unsafe" "encoding" "encoding/json" + "reflect" ) +func createEncoderOfMarshaler(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder { + if typ == marshalerType { + checkIsEmpty := createCheckIsEmpty(cfg, typ) + var encoder ValEncoder = &directMarshalerEncoder{ + checkIsEmpty: checkIsEmpty, + } + return encoder + } + if typ.Implements(marshalerType) { + checkIsEmpty := createCheckIsEmpty(cfg, typ) + var encoder ValEncoder = &marshalerEncoder{ + valType: reflect2.Type2(typ), + checkIsEmpty: checkIsEmpty, + } + return encoder + } + ptrType := reflect.PtrTo(typ) + if prefix != "" && ptrType.Implements(marshalerType) { + checkIsEmpty := createCheckIsEmpty(cfg, ptrType) + var encoder ValEncoder = &marshalerEncoder{ + valType: reflect2.Type2(ptrType), + checkIsEmpty: checkIsEmpty, + } + return &referenceEncoder{encoder} + } + if typ == textMarshalerType { + checkIsEmpty := createCheckIsEmpty(cfg, typ) + var encoder ValEncoder = &directTextMarshalerEncoder{ + checkIsEmpty: checkIsEmpty, + stringEncoder: cfg.EncoderOf(reflect.TypeOf("")), + } + return encoder + } + if typ.Implements(textMarshalerType) { + checkIsEmpty := createCheckIsEmpty(cfg, typ) + var encoder ValEncoder = &textMarshalerEncoder{ + valType: reflect2.Type2(typ), + stringEncoder: cfg.EncoderOf(reflect.TypeOf("")), + checkIsEmpty: checkIsEmpty, + } + return encoder + } + // if prefix is empty, the type is the root type + if prefix != "" && ptrType.Implements(textMarshalerType) { + checkIsEmpty := createCheckIsEmpty(cfg, ptrType) + var encoder ValEncoder = &textMarshalerEncoder{ + valType: reflect2.Type2(ptrType), + stringEncoder: cfg.EncoderOf(reflect.TypeOf("")), + checkIsEmpty: checkIsEmpty, + } + return &referenceEncoder{encoder} + } + return nil +} + type marshalerEncoder struct { checkIsEmpty checkIsEmpty valType reflect2.Type @@ -54,9 +110,9 @@ func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { } type textMarshalerEncoder struct { - valType reflect2.Type - stringEncoder ValEncoder - checkIsEmpty checkIsEmpty + valType reflect2.Type + stringEncoder ValEncoder + checkIsEmpty checkIsEmpty } func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { @@ -81,7 +137,7 @@ func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { type directTextMarshalerEncoder struct { stringEncoder ValEncoder - checkIsEmpty checkIsEmpty + checkIsEmpty checkIsEmpty } func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {