diff options
| author | Alex Flint <[email protected]> | 2016-01-23 21:03:39 -0800 |
|---|---|---|
| committer | Alex Flint <[email protected]> | 2016-01-23 21:03:39 -0800 |
| commit | c0809e537fc01b4a33ced1bf56212837108d7264 (patch) | |
| tree | 4af108e4daa53fd7e2a82d6c72c7f35c50e166a8 /scalar.go | |
| parent | 93247e2f3bf9921859417154cf91f46b2892d0ed (diff) | |
| parent | 8fee8f7bbe5933cfe3ba8c82479b91a8e777e5a0 (diff) | |
Merge pull request #30 from alexflint/scalar_pointers
add support for pointers and TextUnmarshaler
Diffstat (limited to 'scalar.go')
| -rw-r--r-- | scalar.go | 31 |
1 files changed, 23 insertions, 8 deletions
@@ -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 } |
