diff --git a/any_tests/jsoniter_any_string_test.go b/any_tests/jsoniter_any_string_test.go index 3cd3246..bd24db4 100644 --- a/any_tests/jsoniter_any_string_test.go +++ b/any_tests/jsoniter_any_string_test.go @@ -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}`, } diff --git a/extension_tests/decoder_test.go b/extension_tests/decoder_test.go index 49fee90..0f1dd30 100644 --- a/extension_tests/decoder_test.go +++ b/extension_tests/decoder_test.go @@ -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) { diff --git a/reflect_map.go b/reflect_map.go index 7f66a88..547b442 100644 --- a/reflect_map.go +++ b/reflect_map.go @@ -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, } diff --git a/skip_tests/struct_test.go b/skip_tests/struct_test.go index 7f1571d..8392e82 100644 --- a/skip_tests/struct_test.go +++ b/skip_tests/struct_test.go @@ -13,7 +13,7 @@ func init() { `{"hello":{}}`, // valid `{"hello":{}}}`, // invalid `{"hello": { "hello": 1}}`, // valid - `{abc}`, // invalid + `{abc}`, // invalid }, }) } diff --git a/value_tests/map_test.go b/value_tests/map_test.go index 24cf98e..f8ffa5a 100644 --- a/value_tests/map_test.go +++ b/value_tests/map_test.go @@ -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 +} diff --git a/value_tests/raw_message_test.go b/value_tests/raw_message_test.go index b024c4e..eb769a1 100644 --- a/value_tests/raw_message_test.go +++ b/value_tests/raw_message_test.go @@ -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),