From 4f98f818ac8e32d4a8ab61fff720a39b738a80d5 Mon Sep 17 00:00:00 2001 From: Achille Roussel Date: Wed, 22 Jan 2020 18:43:08 -0800 Subject: [PATCH] fix issue 28 --- json/codec.go | 15 ++++++++++++++- json/encode.go | 4 ++++ json/json_test.go | 14 ++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/json/codec.go b/json/codec.go index 1ef84f5..cf7216d 100644 --- a/json/codec.go +++ b/json/codec.go @@ -156,7 +156,7 @@ func constructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr b c = codec{encode: encoder.encodeString, decode: decoder.decodeString} case reflect.Interface: - c = codec{encode: encoder.encodeInterface, decode: constructMaybeEmptyInterfaceDecoderFunc(t)} + c = constructInterfaceCodec(t) case reflect.Array: c = constructArrayCodec(t, seen, canAddr) @@ -711,6 +711,19 @@ func constructPointerDecodeFunc(t reflect.Type, decode decodeFunc) decodeFunc { } } +func constructInterfaceCodec(t reflect.Type) codec { + return codec{ + encode: constructMaybeEmptyInterfaceEncoderFunc(t), + decode: constructMaybeEmptyInterfaceDecoderFunc(t), + } +} + +func constructMaybeEmptyInterfaceEncoderFunc(t reflect.Type) encodeFunc { + return func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) { + return e.encodeMaybeEmptyInterface(b, p, t) + } +} + func constructMaybeEmptyInterfaceDecoderFunc(t reflect.Type) decodeFunc { return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { return d.decodeMaybeEmptyInterface(b, p, t) diff --git a/json/encode.go b/json/encode.go index a44544b..75641bd 100644 --- a/json/encode.go +++ b/json/encode.go @@ -592,6 +592,10 @@ func (e encoder) encodeInterface(b []byte, p unsafe.Pointer) ([]byte, error) { return Append(b, *(*interface{})(p), e.flags) } +func (e encoder) encodeMaybeEmptyInterface(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) { + return Append(b, reflect.NewAt(t, p).Elem().Interface(), e.flags) +} + func (e encoder) encodeUnsupportedTypeError(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) { return b, &UnsupportedTypeError{Type: t} } diff --git a/json/json_test.go b/json/json_test.go index 8c430de..22d9bc6 100644 --- a/json/json_test.go +++ b/json/json_test.go @@ -5,6 +5,7 @@ import ( "compress/gzip" "encoding" "encoding/json" + "errors" "flag" "fmt" "io" @@ -1475,3 +1476,16 @@ func TestGithubIssue26(t *testing.T) { t.Error(err) } } + +func TestGithubIssue28(t *testing.T) { + type A struct { + Err error `json:"err"` + } + + if b, err := Marshal(&A{Err: errors.New("ABC")}); err != nil { + t.Error(err) + } else if string(b) != `{"err":{}}` { + t.Error(string(b)) + } + +}