Merge branch 'v1' of github.com:go-yaml/yaml into v1
diff --git a/decode.go b/decode.go
index ab2b8f7..74eda3c 100644
--- a/decode.go
+++ b/decode.go
@@ -3,6 +3,7 @@
import (
"reflect"
"strconv"
+ "time"
)
const (
@@ -211,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
@@ -279,6 +290,8 @@
return good
}
+var durationType = reflect.TypeOf(time.Duration(0))
+
func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
var tag string
var resolved interface{}
@@ -321,6 +334,14 @@
out.SetInt(int64(resolved))
good = true
}
+ case string:
+ if out.Type() == durationType {
+ d, err := time.ParseDuration(resolved)
+ if err == nil {
+ out.SetInt(int64(d))
+ good = true
+ }
+ }
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
switch resolved := resolved.(type) {
diff --git a/decode_test.go b/decode_test.go
index 5702909..d2b45b3 100644
--- a/decode_test.go
+++ b/decode_test.go
@@ -1,10 +1,11 @@
package yaml_test
import (
- . "launchpad.net/gocheck"
+ . "gopkg.in/check.v1"
"gopkg.in/yaml.v1"
"math"
"reflect"
+ "time"
)
var unmarshalIntTest = 123
@@ -364,6 +365,12 @@
"a: 50cent_of_dollar",
map[string]interface{}{"a": "50cent_of_dollar"},
},
+
+ // Duration
+ {
+ "a: 3s",
+ map[string]time.Duration{"a": 3 * time.Second},
+ },
}
type inlineB struct {
@@ -458,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)
}
diff --git a/encode.go b/encode.go
index c700443..1d928b0 100644
--- a/encode.go
+++ b/encode.go
@@ -4,6 +4,7 @@
"reflect"
"sort"
"strconv"
+ "time"
)
type encoder struct {
@@ -85,7 +86,11 @@
case reflect.String:
e.stringv(tag, in)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- e.intv(tag, in)
+ if in.Type() == durationType {
+ e.stringv(tag, reflect.ValueOf(in.Interface().(time.Duration).String()))
+ } else {
+ e.intv(tag, in)
+ }
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
e.uintv(tag, in)
case reflect.Float32, reflect.Float64:
diff --git a/encode_test.go b/encode_test.go
index 0ab65b9..c7461d5 100644
--- a/encode_test.go
+++ b/encode_test.go
@@ -2,11 +2,12 @@
import (
"fmt"
- . "launchpad.net/gocheck"
"gopkg.in/yaml.v1"
+ . "gopkg.in/check.v1"
"math"
"strconv"
"strings"
+ "time"
)
var marshalIntTest = 123
@@ -212,6 +213,12 @@
}{1, inlineB{2, inlineC{3}}},
"a: 1\nb: 2\nc: 3\n",
},
+
+ // Duration
+ {
+ map[string]time.Duration{"a": 3 * time.Second},
+ "a: 3s\n",
+ },
}
func (s *S) TestMarshal(c *C) {
diff --git a/suite_test.go b/suite_test.go
index 111d756..c5cf1ed 100644
--- a/suite_test.go
+++ b/suite_test.go
@@ -1,7 +1,7 @@
package yaml_test
import (
- . "launchpad.net/gocheck"
+ . "gopkg.in/check.v1"
"testing"
)