field: fix setting pointers. Closes ##16
This commit is contained in:
parent
ebbcf66cbe
commit
8624dc5ae3
16
field.go
16
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
|
// settable (not addresable or not exported) or if the given value's type
|
||||||
// doesn't match the fields type.
|
// doesn't match the fields type.
|
||||||
func (f *Field) Set(val interface{}) error {
|
func (f *Field) Set(val interface{}) error {
|
||||||
// needed to make the field settable
|
// we can't set unexported fields, so be sure this field is exported
|
||||||
v := reflect.Indirect(f.value)
|
|
||||||
|
|
||||||
if !f.IsExported() {
|
if !f.IsExported() {
|
||||||
return errNotExported
|
return errNotExported
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we get here? not sure...
|
// do we get here? not sure...
|
||||||
if !v.CanSet() {
|
if !f.value.CanSet() {
|
||||||
return errNotSettable
|
return errNotSettable
|
||||||
}
|
}
|
||||||
|
|
||||||
given := reflect.ValueOf(val)
|
given := reflect.ValueOf(val)
|
||||||
|
|
||||||
if given.Kind() == reflect.Ptr {
|
if f.value.Kind() != given.Kind() {
|
||||||
given = given.Elem()
|
return fmt.Errorf("wrong kind. got: %s want: %s", given.Kind(), f.value.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.Kind() != given.Kind() {
|
f.value.Set(given)
|
||||||
return fmt.Errorf("wrong kind: %s want: %s", given.Kind(), v.Kind())
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Set(given)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,12 +11,18 @@ type Foo struct {
|
|||||||
B int `structs:"y"`
|
B int `structs:"y"`
|
||||||
C bool `json:"c"`
|
C bool `json:"c"`
|
||||||
d string // not exported
|
d string // not exported
|
||||||
|
E *Baz
|
||||||
x string `xml:"x"` // not exported, with tag
|
x string `xml:"x"` // not exported, with tag
|
||||||
Y []string
|
Y []string
|
||||||
Z map[string]interface{}
|
Z map[string]interface{}
|
||||||
*Bar // embedded
|
*Bar // embedded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Baz struct {
|
||||||
|
A string
|
||||||
|
B int
|
||||||
|
}
|
||||||
|
|
||||||
type Bar struct {
|
type Bar struct {
|
||||||
E string
|
E string
|
||||||
F int
|
F int
|
||||||
@ -35,6 +41,7 @@ func newStruct() *Struct {
|
|||||||
A: "gopher",
|
A: "gopher",
|
||||||
C: true,
|
C: true,
|
||||||
d: "small",
|
d: "small",
|
||||||
|
E: nil,
|
||||||
Y: []string{"example"},
|
Y: []string{"example"},
|
||||||
Z: nil,
|
Z: nil,
|
||||||
}
|
}
|
||||||
@ -108,7 +115,22 @@ func TestField_Set(t *testing.T) {
|
|||||||
t.Error(err)
|
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) {
|
func TestField(t *testing.T) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user