Add unmarshalling null.Time from map[string]interface{}

This commit is contained in:
Jed Borovik 2015-09-10 13:36:31 -04:00
parent 5bebd577e0
commit e5f4f566ed
2 changed files with 30 additions and 5 deletions

23
time.go
View file

@ -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

View file

@ -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) {