1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-20 11:28:49 +02:00

fix #313 support json marshaller type as map key

This commit is contained in:
Tao Wen 2018-10-24 23:28:41 +08:00
parent 5916df66b3
commit 05d041de10
6 changed files with 102 additions and 24 deletions

View File

@ -1,13 +1,13 @@
package test package test
import ( import (
"bytes"
"github.com/json-iterator/go" "github.com/json-iterator/go"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"strconv" "strconv"
"testing" "testing"
"time" "time"
"unsafe" "unsafe"
"bytes"
) )
func Test_customize_type_decoder(t *testing.T) { func Test_customize_type_decoder(t *testing.T) {

View File

@ -64,14 +64,26 @@ func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
return &numericMapKeyDecoder{decoderOfType(ctx, typ)} return &numericMapKeyDecoder{decoderOfType(ctx, typ)}
default: default:
ptrType := reflect2.PtrTo(typ) ptrType := reflect2.PtrTo(typ)
if ptrType.Implements(textMarshalerType) { if ptrType.Implements(unmarshalerType) {
return &referenceDecoder{
&unmarshalerDecoder{
valType: ptrType,
},
}
}
if typ.Implements(unmarshalerType) {
return &unmarshalerDecoder{
valType: typ,
}
}
if ptrType.Implements(textUnmarshalerType) {
return &referenceDecoder{ return &referenceDecoder{
&textUnmarshalerDecoder{ &textUnmarshalerDecoder{
valType: ptrType, valType: ptrType,
}, },
} }
} }
if typ.Implements(textMarshalerType) { if typ.Implements(textUnmarshalerType) {
return &textUnmarshalerDecoder{ return &textUnmarshalerDecoder{
valType: typ, valType: typ,
} }

View File

@ -2,7 +2,9 @@ package test
import ( import (
"encoding/json" "encoding/json"
"fmt"
"math/big" "math/big"
"time"
) )
func init() { func init() {
@ -27,6 +29,8 @@ func init() {
nilMap, nilMap,
&nilMap, &nilMap,
map[string]*json.RawMessage{"hello": pRawMessage(json.RawMessage("[]"))}, map[string]*json.RawMessage{"hello": pRawMessage(json.RawMessage("[]"))},
map[Date]bool{{}: true},
map[Date2]bool{{}: true},
) )
unmarshalCases = append(unmarshalCases, unmarshalCase{ unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*map[string]string)(nil), ptr: (*map[string]string)(nil),
@ -37,6 +41,20 @@ func init() {
}, unmarshalCase{ }, unmarshalCase{
ptr: (*map[string]*json.RawMessage)(nil), ptr: (*map[string]*json.RawMessage)(nil),
input: "{\"test\":[{\"key\":\"value\"}]}", input: "{\"test\":[{\"key\":\"value\"}]}",
}, unmarshalCase{
ptr: (*map[Date]bool)(nil),
input: `{
"2018-12-12": true,
"2018-12-13": true,
"2018-12-14": true
}`,
}, unmarshalCase{
ptr: (*map[Date2]bool)(nil),
input: `{
"2018-12-12": true,
"2018-12-13": true,
"2018-12-14": true
}`,
}) })
} }
@ -49,3 +67,51 @@ type MyString string
func (ms MyString) Hello() string { func (ms MyString) Hello() string {
return string(ms) return string(ms)
} }
type Date struct {
time.Time
}
func (d *Date) UnmarshalJSON(b []byte) error {
dateStr := string(b) // something like `"2017-08-20"`
if dateStr == "null" {
return nil
}
t, err := time.Parse(`"2006-01-02"`, dateStr)
if err != nil {
return fmt.Errorf("cant parse date: %#v", err)
}
d.Time = t
return nil
}
func (d *Date) MarshalJSON() ([]byte, error) {
return []byte(d.Time.Format("2006-01-02")), nil
}
type Date2 struct {
time.Time
}
func (d Date2) UnmarshalJSON(b []byte) error {
dateStr := string(b) // something like `"2017-08-20"`
if dateStr == "null" {
return nil
}
t, err := time.Parse(`"2006-01-02"`, dateStr)
if err != nil {
return fmt.Errorf("cant parse date: %#v", err)
}
d.Time = t
return nil
}
func (d Date2) MarshalJSON() ([]byte, error) {
return []byte(d.Time.Format("2006-01-02")), nil
}

View File

@ -7,12 +7,12 @@ import (
func init() { func init() {
marshalCases = append(marshalCases, marshalCases = append(marshalCases,
json.RawMessage("{}"), json.RawMessage("{}"),
selectedMarshalCase{struct { struct {
Env string `json:"env"` Env string `json:"env"`
Extra json.RawMessage `json:"extra,omitempty"` Extra json.RawMessage `json:"extra,omitempty"`
}{ }{
Env: "jfdk", Env: "jfdk",
}}, },
) )
unmarshalCases = append(unmarshalCases, unmarshalCase{ unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*json.RawMessage)(nil), ptr: (*json.RawMessage)(nil),