diff options
Diffstat (limited to 'scalar.go')
| -rw-r--r-- | scalar.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/scalar.go b/scalar.go new file mode 100644 index 0000000..a3bafe4 --- /dev/null +++ b/scalar.go @@ -0,0 +1,63 @@ +package arg + +import ( + "encoding" + "fmt" + "reflect" + "strconv" + "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 { + x, err := time.ParseDuration(s) + if err != nil { + return err + } + v.Set(reflect.ValueOf(x)) + return nil + } + + switch v.Kind() { + case reflect.String: + v.SetString(s) + case reflect.Bool: + x, err := strconv.ParseBool(s) + if err != nil { + return err + } + v.SetBool(x) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + x, err := strconv.ParseInt(s, 10, v.Type().Bits()) + if err != nil { + return err + } + v.SetInt(x) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + x, err := strconv.ParseUint(s, 10, v.Type().Bits()) + if err != nil { + return err + } + v.SetUint(x) + case reflect.Float32, reflect.Float64: + x, err := strconv.ParseFloat(s, v.Type().Bits()) + if err != nil { + return err + } + v.SetFloat(x) + default: + return fmt.Errorf("not a scalar type: %s", v.Kind()) + } + return nil +} |
