summaryrefslogtreecommitdiff
path: root/scalar.go
diff options
context:
space:
mode:
authorAlex Flint <[email protected]>2016-01-23 21:03:39 -0800
committerAlex Flint <[email protected]>2016-01-23 21:03:39 -0800
commitc0809e537fc01b4a33ced1bf56212837108d7264 (patch)
tree4af108e4daa53fd7e2a82d6c72c7f35c50e166a8 /scalar.go
parent93247e2f3bf9921859417154cf91f46b2892d0ed (diff)
parent8fee8f7bbe5933cfe3ba8c82479b91a8e777e5a0 (diff)
Merge pull request #30 from alexflint/scalar_pointers
add support for pointers and TextUnmarshaler
Diffstat (limited to 'scalar.go')
-rw-r--r--scalar.go31
1 files changed, 23 insertions, 8 deletions
diff --git a/scalar.go b/scalar.go
index a3bafe4..67b4540 100644
--- a/scalar.go
+++ b/scalar.go
@@ -8,19 +8,33 @@ import (
"time"
)
-var (
- durationType = reflect.TypeOf(time.Duration(0))
- textUnmarshalerType = reflect.TypeOf([]encoding.TextUnmarshaler{}).Elem()
-)
-
// set a value from a string
func setScalar(v reflect.Value, s string) error {
if !v.CanSet() {
return fmt.Errorf("field is not exported")
}
- // If we have a time.Duration then use time.ParseDuration
- if v.Type() == durationType {
+ // If we have a nil pointer then allocate a new object
+ if v.Kind() == reflect.Ptr && v.IsNil() {
+ v.Set(reflect.New(v.Type().Elem()))
+ }
+
+ // Get the object as an interface
+ scalar := v.Interface()
+
+ // If it implements encoding.TextUnmarshaler then use that
+ if scalar, ok := scalar.(encoding.TextUnmarshaler); ok {
+ return scalar.UnmarshalText([]byte(s))
+ }
+
+ // If we have a pointer then dereference it
+ if v.Kind() == reflect.Ptr {
+ v = v.Elem()
+ }
+
+ // Switch on concrete type
+ switch scalar.(type) {
+ case time.Duration:
x, err := time.ParseDuration(s)
if err != nil {
return err
@@ -29,6 +43,7 @@ func setScalar(v reflect.Value, s string) error {
return nil
}
+ // Switch on kind so that we can handle derived types
switch v.Kind() {
case reflect.String:
v.SetString(s)
@@ -57,7 +72,7 @@ func setScalar(v reflect.Value, s string) error {
}
v.SetFloat(x)
default:
- return fmt.Errorf("not a scalar type: %s", v.Kind())
+ return fmt.Errorf("cannot parse argument into %s", v.Type().String())
}
return nil
}