Add unmarshalling null.Time from map[string]interface{}
This commit is contained in:
parent
5bebd577e0
commit
e5f4f566ed
2 changed files with 30 additions and 5 deletions
23
time.go
23
time.go
|
@ -71,16 +71,29 @@ func (t Time) MarshalJSON() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON implements json.Unmarshaler.
|
// UnmarshalJSON implements json.Unmarshaler.
|
||||||
// It supports time, string and null input.
|
// It supports string, map[string]interface{},
|
||||||
|
// and null input.
|
||||||
func (t *Time) UnmarshalJSON(data []byte) error {
|
func (t *Time) UnmarshalJSON(data []byte) error {
|
||||||
var err error
|
var err error
|
||||||
var v interface{}
|
var v interface{}
|
||||||
json.Unmarshal(data, &v)
|
if err = json.Unmarshal(data, &v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
switch x := v.(type) {
|
switch x := v.(type) {
|
||||||
case time.Time:
|
|
||||||
t.Time = x
|
|
||||||
case string:
|
case string:
|
||||||
t.Time, err = time.Parse(time.RFC3339, x)
|
err = t.Time.UnmarshalJSON(data)
|
||||||
|
case map[string]interface{}:
|
||||||
|
ti, tiOK := x["Time"].(string)
|
||||||
|
valid, validOK := x["Valid"].(bool)
|
||||||
|
if !tiOK || !validOK {
|
||||||
|
err = fmt.Errorf("json: unmarshalling map[string]interface{} into Go value of type null.Time requires key \"Time\" to be of type string and key \"Valid\" to be of type bool; found %T and %T, respectively", x["Time"], x["Valid"])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
err = t.Time.UnmarshalJSON([]byte(`"` + ti + `"`))
|
||||||
|
t.Valid = valid
|
||||||
|
if err == nil && t.Valid == false {
|
||||||
|
return nil // Return here to prevent `Valid` from being set to true based on nil error below.
|
||||||
|
}
|
||||||
case nil:
|
case nil:
|
||||||
t.Valid = false
|
t.Valid = false
|
||||||
return nil
|
return nil
|
||||||
|
|
12
time_test.go
12
time_test.go
|
@ -11,6 +11,8 @@ var (
|
||||||
timeJSON = []byte(`"` + timeString + `"`)
|
timeJSON = []byte(`"` + timeString + `"`)
|
||||||
blankTimeJSON = []byte(`null`)
|
blankTimeJSON = []byte(`null`)
|
||||||
timeValue, _ = time.Parse(time.RFC3339, timeString)
|
timeValue, _ = time.Parse(time.RFC3339, timeString)
|
||||||
|
timeMap = []byte(`{"Time":"2012-12-21T21:21:21Z","Valid":true}`)
|
||||||
|
invalidMap = []byte(`{"Time":"0001-01-01T00:00:00Z","Valid":false}`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUnmarshalTimeString(t *testing.T) {
|
func TestUnmarshalTimeString(t *testing.T) {
|
||||||
|
@ -23,6 +25,16 @@ func TestUnmarshalTimeString(t *testing.T) {
|
||||||
err = json.Unmarshal(blankTimeJSON, &blank)
|
err = json.Unmarshal(blankTimeJSON, &blank)
|
||||||
maybePanic(err)
|
maybePanic(err)
|
||||||
assertNullTime(t, blank, "blank time json")
|
assertNullTime(t, blank, "blank time json")
|
||||||
|
|
||||||
|
var fromMap Time
|
||||||
|
err = json.Unmarshal(timeMap, &fromMap)
|
||||||
|
maybePanic(err)
|
||||||
|
assertTime(t, fromMap, "map time json")
|
||||||
|
|
||||||
|
var invalid Time
|
||||||
|
err = json.Unmarshal(invalidMap, &invalid)
|
||||||
|
maybePanic(err)
|
||||||
|
assertNullTime(t, invalid, "map invalid time json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMarshalTime(t *testing.T) {
|
func TestMarshalTime(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue