diff --git a/field.go b/field.go index 4b5e15b..1178b0c 100644 --- a/field.go +++ b/field.go @@ -84,6 +84,13 @@ func (f *Field) Set(val interface{}) error { return nil } +// Zero sets the field to its zero value. It returns an error if the field is not +// settable (not addressable or not exported). +func (f *Field) Zero() error { + zero := reflect.Zero(f.value.Type()).Interface() + return f.Set(zero) +} + // Fields returns a slice of Fields. This is particular handy to get the fields // of a nested struct . A struct tag with the content of "-" ignores the // checking of that particular field. Example: diff --git a/field_test.go b/field_test.go index 379ceff..b77e951 100644 --- a/field_test.go +++ b/field_test.go @@ -133,6 +133,65 @@ func TestField_Set(t *testing.T) { } } +func TestField_Zero(t *testing.T) { + s := newStruct() + + f := s.Field("A") + err := f.Zero() + if err != nil { + t.Error(err) + } + + if f.Value().(string) != "" { + t.Errorf("Zeroed value is wrong: %s want: %s", f.Value().(string), "") + } + + f = s.Field("Y") + err = f.Zero() + if err != nil { + t.Error(err) + } + + sliceLen := len(f.Value().([]string)) + if sliceLen != 0 { + t.Errorf("Zeroed values slice length is wrong: %d, want: %d", sliceLen, 0) + } + + f = s.Field("C") + err = f.Zero() + if err != nil { + t.Error(err) + } + + if f.Value().(bool) { + t.Errorf("Zeroed value is wrong: %t want: %t", f.Value().(bool), false) + } + + // let's access an unexported field, which should give an error + f = s.Field("d") + err = f.Zero() + if err != errNotExported { + t.Error(err) + } + + f = s.Field("Bar") + err = f.Zero() + if err != nil { + t.Error(err) + } + + f = s.Field("E") + err = f.Zero() + if err != nil { + t.Error(err) + } + + v := s.Field("E").value + if !v.IsNil() { + t.Errorf("could not set baz. Got: %s Want: ", v.Interface()) + } +} + func TestField(t *testing.T) { s := newStruct()