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