Merge pull request #57 from asdine/setOnNestedField

Fix set value on nested field
This commit is contained in:
Fatih Arslan 2016-06-01 12:31:17 +03:00
commit 5ada2f449b
2 changed files with 32 additions and 1 deletions

View File

@ -117,7 +117,16 @@ func (f *Field) Field(name string) *Field {
// FieldOk returns the field from a nested struct. The boolean returns whether
// the field was found (true) or not (false).
func (f *Field) FieldOk(name string) (*Field, bool) {
v := strctVal(f.value.Interface())
value := &f.value
// value must be settable so we need to make sure it holds the address of the
// variable and not a copy, so we can pass the pointer to strctVal instead of a
// copy (which is not assigned to any variable, hence not settable).
// see "https://blog.golang.org/laws-of-reflection#TOC_8."
if f.value.Kind() != reflect.Ptr {
a := f.value.Addr()
value = &a
}
v := strctVal(value.Interface())
t := v.Type()
field, ok := t.FieldByName(name)

View File

@ -1022,6 +1022,28 @@ func TestNestedNilPointer(t *testing.T) {
_ = Map(personWithDogWithCollar) // Doesn't panic
}
func TestSetValueOnNestedField(t *testing.T) {
type Base struct {
ID int
}
type User struct {
Base
Name string
}
u := User{}
s := New(&u)
f := s.Field("Base").Field("ID")
err := f.Set(10)
if err != nil {
t.Errorf("Error %v", err)
}
if f.Value().(int) != 10 {
t.Errorf("Value should be equal to 10, got %v", f.Value())
}
}
type Person struct {
Name string
Age int