1package test 2 3import ( 4 "encoding/json" 5 "fmt" 6 "math/big" 7 "time" 8) 9 10func init() { 11 var pRawMessage = func(val json.RawMessage) *json.RawMessage { 12 return &val 13 } 14 nilMap := map[string]string(nil) 15 marshalCases = append(marshalCases, 16 map[string]interface{}{"abc": 1}, 17 map[string]MyInterface{"hello": MyString("world")}, 18 map[*big.Float]string{big.NewFloat(1.2): "2"}, 19 map[string]interface{}{ 20 "3": 3, 21 "1": 1, 22 "2": 2, 23 }, 24 map[uint64]interface{}{ 25 uint64(1): "a", 26 uint64(2): "a", 27 uint64(4): "a", 28 }, 29 nilMap, 30 &nilMap, 31 map[string]*json.RawMessage{"hello": pRawMessage(json.RawMessage("[]"))}, 32 map[Date]bool{{}: true}, 33 map[Date2]bool{{}: true}, 34 ) 35 unmarshalCases = append(unmarshalCases, unmarshalCase{ 36 ptr: (*map[string]string)(nil), 37 input: `{"k\"ey": "val"}`, 38 }, unmarshalCase{ 39 ptr: (*map[string]string)(nil), 40 input: `null`, 41 }, unmarshalCase{ 42 ptr: (*map[string]*json.RawMessage)(nil), 43 input: "{\"test\":[{\"key\":\"value\"}]}", 44 }, unmarshalCase{ 45 ptr: (*map[Date]bool)(nil), 46 input: `{ 47 "2018-12-12": true, 48 "2018-12-13": true, 49 "2018-12-14": true 50 }`, 51 }, unmarshalCase{ 52 ptr: (*map[Date2]bool)(nil), 53 input: `{ 54 "2018-12-12": true, 55 "2018-12-13": true, 56 "2018-12-14": true 57 }`, 58 }) 59} 60 61type MyInterface interface { 62 Hello() string 63} 64 65type MyString string 66 67func (ms MyString) Hello() string { 68 return string(ms) 69} 70 71type Date struct { 72 time.Time 73} 74 75func (d *Date) UnmarshalJSON(b []byte) error { 76 dateStr := string(b) // something like `"2017-08-20"` 77 78 if dateStr == "null" { 79 return nil 80 } 81 82 t, err := time.Parse(`"2006-01-02"`, dateStr) 83 if err != nil { 84 return fmt.Errorf("cant parse date: %#v", err) 85 } 86 87 d.Time = t 88 return nil 89} 90 91func (d *Date) MarshalJSON() ([]byte, error) { 92 return []byte(d.Time.Format("2006-01-02")), nil 93} 94 95type Date2 struct { 96 time.Time 97} 98 99func (d Date2) UnmarshalJSON(b []byte) error { 100 dateStr := string(b) // something like `"2017-08-20"` 101 102 if dateStr == "null" { 103 return nil 104 } 105 106 t, err := time.Parse(`"2006-01-02"`, dateStr) 107 if err != nil { 108 return fmt.Errorf("cant parse date: %#v", err) 109 } 110 111 d.Time = t 112 return nil 113} 114 115func (d Date2) MarshalJSON() ([]byte, error) { 116 return []byte(d.Time.Format("2006-01-02")), nil 117} 118