diff --git a/field.go b/field.go index e557e8a..093dd40 100644 --- a/field.go +++ b/field.go @@ -63,29 +63,23 @@ func (f *Field) Kind() reflect.Kind { // settable (not addresable or not exported) or if the given value's type // doesn't match the fields type. func (f *Field) Set(val interface{}) error { - // needed to make the field settable - v := reflect.Indirect(f.value) - + // we can't set unexported fields, so be sure this field is exported if !f.IsExported() { return errNotExported } // do we get here? not sure... - if !v.CanSet() { + if !f.value.CanSet() { return errNotSettable } given := reflect.ValueOf(val) - if given.Kind() == reflect.Ptr { - given = given.Elem() + if f.value.Kind() != given.Kind() { + return fmt.Errorf("wrong kind. got: %s want: %s", given.Kind(), f.value.Kind()) } - if v.Kind() != given.Kind() { - return fmt.Errorf("wrong kind: %s want: %s", given.Kind(), v.Kind()) - } - - v.Set(given) + f.value.Set(given) return nil } diff --git a/field_test.go b/field_test.go index 36d40e7..46187d6 100644 --- a/field_test.go +++ b/field_test.go @@ -11,12 +11,18 @@ type Foo struct { B int `structs:"y"` C bool `json:"c"` d string // not exported + E *Baz x string `xml:"x"` // not exported, with tag Y []string Z map[string]interface{} *Bar // embedded } +type Baz struct { + A string + B int +} + type Bar struct { E string F int @@ -35,6 +41,7 @@ func newStruct() *Struct { A: "gopher", C: true, d: "small", + E: nil, Y: []string{"example"}, Z: nil, } @@ -108,7 +115,22 @@ func TestField_Set(t *testing.T) { t.Error(err) } - // TODO: let's access a non addresable field, which should give an error + baz := &Baz{ + A: "helloWorld", + B: 42, + } + + f = s.Field("E") + err = f.Set(baz) + if err != nil { + t.Error(err) + } + + ba := s.Field("E").Value().(*Baz) + + if ba.A != "helloWorld" { + t.Errorf("could not set baz. Got: %s Want: helloWorld", ba.A) + } } func TestField(t *testing.T) {