Fix Setter handling on non-pointer fields. Fixes #8.
diff --git a/decode.go b/decode.go index 9480191..74eda3c 100644 --- a/decode.go +++ b/decode.go
@@ -212,6 +212,16 @@ // returned to call SetYAML() with the value of *out once it's defined. // func (d *decoder) setter(tag string, out *reflect.Value, good *bool) (set func()) { + if (*out).Kind() != reflect.Ptr && (*out).CanAddr() { + setter, _ := (*out).Addr().Interface().(Setter) + if setter != nil { + var arg interface{} + *out = reflect.ValueOf(&arg).Elem() + return func() { + *good = setter.SetYAML(tag, arg) + } + } + } again := true for again { again = false
diff --git a/decode_test.go b/decode_test.go index ab3a7fb..d2b45b3 100644 --- a/decode_test.go +++ b/decode_test.go
@@ -465,17 +465,31 @@ return true } -type typeWithSetterField struct { +type setterPointerType struct { Field *typeWithSetter "_" } -func (s *S) TestUnmarshalWithSetter(c *C) { +type setterValueType struct { + Field typeWithSetter "_" +} + +func (s *S) TestUnmarshalWithPointerSetter(c *C) { for _, item := range setterTests { - obj := &typeWithSetterField{} + obj := &setterPointerType{} err := yaml.Unmarshal([]byte(item.data), obj) c.Assert(err, IsNil) - c.Assert(obj.Field, NotNil, - Commentf("Pointer not initialized (%#v)", item.value)) + c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) + c.Assert(obj.Field.tag, Equals, item.tag) + c.Assert(obj.Field.value, DeepEquals, item.value) + } +} + +func (s *S) TestUnmarshalWithValueSetter(c *C) { + for _, item := range setterTests { + obj := &setterValueType{} + err := yaml.Unmarshal([]byte(item.data), obj) + c.Assert(err, IsNil) + c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) c.Assert(obj.Field.tag, Equals, item.tag) c.Assert(obj.Field.value, DeepEquals, item.value) }