1
0
mirror of https://github.com/json-iterator/go.git synced 2024-11-24 08:22:14 +02:00

Fix custom marshaler for enum types

When MarshalJSON was defined on a pointer receiver custom enum type
marshaling/unmarshaling was panicing since the underlying primitive type
was treated as a pointer.

Since method set for pointer receivers includes value receiver methods
we don't really need optionalEncoder and can just use marshalEncoder
directly.
This commit is contained in:
Oleg Shaldybin 2017-09-14 23:04:54 -07:00
parent eef35e549b
commit ae57d167e8
3 changed files with 51 additions and 1 deletions

View File

@ -476,7 +476,6 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error
templateInterface: extractInterface(templateInterface),
checkIsEmpty: checkIsEmpty,
}
encoder = &optionalEncoder{encoder}
return encoder, nil
}
if typ.Implements(textMarshalerType) {

View File

@ -661,6 +661,7 @@ func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
templateInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
marshaler := (*realInterface).(json.Marshaler)
bytes, err := marshaler.MarshalJSON()
if err != nil {
stream.Error = err

View File

@ -0,0 +1,50 @@
package jsoniter
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
type MyEnum int64
const (
MyEnumA MyEnum = iota
MyEnumB
)
func (m *MyEnum) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"foo-%d"`, int(*m))), nil
}
func (m *MyEnum) UnmarshalJSON(jb []byte) error {
switch string(jb) {
case `"foo-1"`:
*m = MyEnumB
default:
*m = MyEnumA
}
return nil
}
func Test_custom_marshaler_on_enum(t *testing.T) {
type Wrapper struct {
Payload interface{}
}
type Wrapper2 struct {
Payload MyEnum
}
should := require.New(t)
w := Wrapper{Payload: MyEnumB}
jb, err := Marshal(w)
should.Equal(nil, err)
should.Equal(`{"Payload":"foo-1"}`, string(jb))
var w2 Wrapper2
err = Unmarshal(jb, &w2)
should.Equal(nil, err)
should.Equal(MyEnumB, w2.Payload)
}