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{ var stringConvertMap = map[string]string{
"null": "", "null": "",
"321.1": "321.1", "321.1": "321.1",
`"1.1"`: "1.1", `"1.1"`: "1.1",
`"-123.1"`: "-123.1", `"-123.1"`: "-123.1",
"0.0": "0.0", "0.0": "0.0",
"0": "0", "0": "0",
`"0"`: "0", `"0"`: "0",
`"0.0"`: "0.0", `"0.0"`: "0.0",
`"00.0"`: "00.0", `"00.0"`: "00.0",
"true": "true", "true": "true",
"false": "false", "false": "false",
`"true"`: "true", `"true"`: "true",
`"false"`: "false", `"false"`: "false",
`"true123"`: "true123", `"true123"`: "true123",
`"+1"`: "+1", `"+1"`: "+1",
"[]": "[]", "[]": "[]",
"[1,2]": "[1,2]", "[1,2]": "[1,2]",
"{}": "{}", "{}": "{}",
`{"a":1, "stream":true}`: `{"a":1, "stream":true}`, `{"a":1, "stream":true}`: `{"a":1, "stream":true}`,
} }

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

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

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),