Skip to content

Commit

Permalink
Merge pull request #13 from weberr13/ignore-unrequired-nil
Browse files Browse the repository at this point in the history
Ignore nil value for unrequired fields
  • Loading branch information
meriburgess authored Oct 24, 2019
2 parents a04b5c0 + 7e14af5 commit 7c4498b
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
14 changes: 10 additions & 4 deletions decode/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ type LivesInStruct struct {
}

type TimedStruct struct {
Name string
Name string
UpdateTime *time.Time
}

Expand Down Expand Up @@ -494,9 +494,15 @@ func TestDecodeNestedObject(t *testing.T) {
_, err := decode.UnmarshalJSONInto([]byte(b), &TimedStruct{}, nil)
So(err, ShouldNotBeNil)
})
Convey("Test decoding -- cannot decode when field is set to null", t, func() {
b := `{ "livesIn" : { "age": 7, "name": null, "lost": false}}`
_, err := decode.UnmarshalJSONInto([]byte(b), &LivesInStruct{}, SchemaPathFactory)
Convey("Test decoding -- cannot decode when required field is set to null", t, func() {
b := `{ "name": null, "updateTime": "2019-10-21T14:56:28.292468-06:00"}`
_, err := decode.UnmarshalJSONInto([]byte(b), &TimedStruct{}, SchemaPathFactory)
So(err, ShouldNotBeNil)
})
Convey("Test decoding -- allow decode when unrequired field is set to null", t, func() {
b := `{ "name": "john", "updateTime": null }`
i, err := decode.UnmarshalJSONInto([]byte(b), &TimedStruct{}, SchemaPathFactory)
So(err, ShouldBeNil)
So(i.(*TimedStruct), ShouldResemble, &TimedStruct{Name: "john"})
})
}
20 changes: 12 additions & 8 deletions decode/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,11 @@ func DecodeInto(m map[string]interface{}, o interface{}, pf PathFactory) (interf
}
continue
case nil:
return nil, fmt.Errorf("Invalid value: Null not allowed field '%v'", fldName)
// if field is required, return an error, otherwise ignore it
if field.Kind() != reflect.Ptr {
return nil, fmt.Errorf("Invalid value: Null not allowed for required field '%v'\n", fldName)
}
continue
}

// use reflection to set the field
Expand Down Expand Up @@ -231,7 +235,7 @@ func decodeIntoArray(field reflect.Value, iter iterator, len int, pf PathFactory
}

// If s is a slice of pointers and pV is not a pointer
if s.Type().Elem().Kind() == reflect.Ptr && pV.Kind() != reflect.Ptr {
if s.Type().Elem().Kind() == reflect.Ptr && pV.Kind() != reflect.Ptr {
// Init a new zero value of that type in the index of slice, then set with pV value
s.Index(i).Set(reflect.New(s.Index(i).Type().Elem()))
s.Index(i).Elem().Set(pV)
Expand All @@ -240,7 +244,7 @@ func decodeIntoArray(field reflect.Value, iter iterator, len int, pf PathFactory
}

//if s is NOT a slice of pointers and pV is a pointer, deref it before calling Set()
if s.Type().Elem().Kind() != reflect.Ptr && pV.Kind() == reflect.Ptr {
if s.Type().Elem().Kind() != reflect.Ptr && pV.Kind() == reflect.Ptr {
pV = pV.Elem()
}
s.Index(i).Set(pV)
Expand Down Expand Up @@ -359,18 +363,18 @@ func parseAndSetField(path string, field, newField, val reflect.Value) error {
unmarshaler, ok := newField.Interface().(json.Unmarshaler)
if ok {
// marshal val back to []byte since it was converted to some underlying type (int/string)
valBytes, err := json.Marshal(val.Interface());
valBytes, err := json.Marshal(val.Interface())
if err != nil {
return fmt.Errorf("Cannot convert value to []byte when attempting to set '%s': %s", path, err)
return fmt.Errorf("Cannot convert value to []byte when attempting to set '%s': %s\n", path, err)
}
// unmarshal valBytes back into newField object via the unmarshaler
err = unmarshaler.UnmarshalJSON(valBytes)
if err != nil {
return fmt.Errorf("Cannot unmarshal byte values for field '%s': %s", path, err)
return fmt.Errorf("Cannot unmarshal byte values for field '%s': %s\n", path, err)
}
// set field to the value unmarshaled into newField
field.Set(newField)
return nil
}
return fmt.Errorf("cannot convert value (%v) to field '%s' type", val, path)
}
return fmt.Errorf("cannot convert value (%v) to field '%s' type\n", val, path)
}

0 comments on commit 7c4498b

Please sign in to comment.