mirror of
https://github.com/json-iterator/go.git
synced 2025-04-20 11:28:49 +02:00
* Map keys of custom types should serialize/deserialize using MarshalText/UnmarshalText when available - this brings marshaling/unmarshaling behavior in line with encoding/json - in general, any types that implement the interfaces from the encoding package (TextUnmarshaler, TextMarshaler, etc.) should use the provided method when available
133 lines
2.5 KiB
Go
133 lines
2.5 KiB
Go
package test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/big"
|
|
"time"
|
|
)
|
|
|
|
func init() {
|
|
var pRawMessage = func(val json.RawMessage) *json.RawMessage {
|
|
return &val
|
|
}
|
|
nilMap := map[string]string(nil)
|
|
marshalCases = append(marshalCases,
|
|
map[string]interface{}{"abc": 1},
|
|
map[string]MyInterface{"hello": MyString("world")},
|
|
map[*big.Float]string{big.NewFloat(1.2): "2"},
|
|
map[string]interface{}{
|
|
"3": 3,
|
|
"1": 1,
|
|
"2": 2,
|
|
},
|
|
map[uint64]interface{}{
|
|
uint64(1): "a",
|
|
uint64(2): "a",
|
|
uint64(4): "a",
|
|
},
|
|
nilMap,
|
|
&nilMap,
|
|
map[string]*json.RawMessage{"hello": pRawMessage(json.RawMessage("[]"))},
|
|
map[Date]bool{{}: true},
|
|
map[Date2]bool{{}: true},
|
|
map[customKey]string{customKey(1): "bar"},
|
|
)
|
|
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
|
ptr: (*map[string]string)(nil),
|
|
input: `{"k\"ey": "val"}`,
|
|
}, unmarshalCase{
|
|
ptr: (*map[string]string)(nil),
|
|
input: `null`,
|
|
}, 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
|
|
}`,
|
|
}, unmarshalCase{
|
|
ptr: (*map[customKey]string)(nil),
|
|
input: `{"foo": "bar"}`,
|
|
})
|
|
}
|
|
|
|
type MyInterface interface {
|
|
Hello() string
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
type customKey int32
|
|
|
|
func (c customKey) MarshalText() ([]byte, error) {
|
|
return []byte("foo"), nil
|
|
}
|
|
|
|
func (c *customKey) UnmarshalText(value []byte) error {
|
|
*c = 1
|
|
return nil
|
|
}
|