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 }