Selaa lähdekoodia

fix #313 support json marshaller type as map key

Tao Wen 7 vuotta sitten
vanhempi
commit
05d041de10

+ 18 - 18
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}`,
 }
 

+ 1 - 1
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) {

+ 14 - 2
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,
 			}

+ 1 - 1
skip_tests/struct_test.go

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

+ 66 - 0
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
+}

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