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

@ -8,24 +8,24 @@ import (
)
var stringConvertMap = map[string]string{
"null": "",
"321.1": "321.1",
`"1.1"`: "1.1",
`"-123.1"`: "-123.1",
"0.0": "0.0",
"0": "0",
`"0"`: "0",
`"0.0"`: "0.0",
`"00.0"`: "00.0",
"true": "true",
"false": "false",
`"true"`: "true",
`"false"`: "false",
`"true123"`: "true123",
`"+1"`: "+1",
"[]": "[]",
"[1,2]": "[1,2]",
"{}": "{}",
"null": "",
"321.1": "321.1",
`"1.1"`: "1.1",
`"-123.1"`: "-123.1",
"0.0": "0.0",
"0": "0",
`"0"`: "0",
`"0.0"`: "0.0",
`"00.0"`: "00.0",
"true": "true",
"false": "false",
`"true"`: "true",
`"false"`: "false",
`"true123"`: "true123",
`"+1"`: "+1",
"[]": "[]",
"[1,2]": "[1,2]",
"{}": "{}",
`{"a":1, "stream":true}`: `{"a":1, "stream":true}`,
}

View File

@ -1,13 +1,13 @@
package test
import (
"bytes"
"github.com/json-iterator/go"
"github.com/stretchr/testify/require"
"strconv"
"testing"
"time"
"unsafe"
"bytes"
)
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)}
default:
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{
&textUnmarshalerDecoder{
valType: ptrType,
},
}
}
if typ.Implements(textMarshalerType) {
if typ.Implements(textUnmarshalerType) {
return &textUnmarshalerDecoder{
valType: typ,
}

View File

@ -13,7 +13,7 @@ func init() {
`{"hello":{}}`, // valid
`{"hello":{}}}`, // invalid
`{"hello": { "hello": 1}}`, // valid
`{abc}`, // invalid
`{abc}`, // invalid
},
})
}

View File

@ -2,7 +2,9 @@ package test
import (
"encoding/json"
"fmt"
"math/big"
"time"
)
func init() {
@ -27,6 +29,8 @@ func init() {
nilMap,
&nilMap,
map[string]*json.RawMessage{"hello": pRawMessage(json.RawMessage("[]"))},
map[Date]bool{{}: true},
map[Date2]bool{{}: true},
)
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*map[string]string)(nil),
@ -37,6 +41,20 @@ func init() {
}, unmarshalCase{
ptr: (*map[string]*json.RawMessage)(nil),
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 {
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() {
marshalCases = append(marshalCases,
json.RawMessage("{}"),
selectedMarshalCase{struct {
struct {
Env string `json:"env"`
Extra json.RawMessage `json:"extra,omitempty"`
}{
Env: "jfdk",
}},
},
)
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*json.RawMessage)(nil),