|
@@ -69,44 +69,7 @@ func Repr(v interface{}) string {
|
|
|
val = val.Elem()
|
|
|
}
|
|
|
|
|
|
- switch vt := val.Interface().(type) {
|
|
|
- case bool:
|
|
|
- return strconv.FormatBool(vt)
|
|
|
- case error:
|
|
|
- return vt.Error()
|
|
|
- case float32:
|
|
|
- return strconv.FormatFloat(float64(vt), 'f', -1, 32)
|
|
|
- case float64:
|
|
|
- return strconv.FormatFloat(vt, 'f', -1, 64)
|
|
|
- case fmt.Stringer:
|
|
|
- return vt.String()
|
|
|
- case int:
|
|
|
- return strconv.Itoa(vt)
|
|
|
- case int8:
|
|
|
- return strconv.Itoa(int(vt))
|
|
|
- case int16:
|
|
|
- return strconv.Itoa(int(vt))
|
|
|
- case int32:
|
|
|
- return strconv.Itoa(int(vt))
|
|
|
- case int64:
|
|
|
- return strconv.FormatInt(vt, 10)
|
|
|
- case string:
|
|
|
- return vt
|
|
|
- case uint:
|
|
|
- return strconv.FormatUint(uint64(vt), 10)
|
|
|
- case uint8:
|
|
|
- return strconv.FormatUint(uint64(vt), 10)
|
|
|
- case uint16:
|
|
|
- return strconv.FormatUint(uint64(vt), 10)
|
|
|
- case uint32:
|
|
|
- return strconv.FormatUint(uint64(vt), 10)
|
|
|
- case uint64:
|
|
|
- return strconv.FormatUint(vt, 10)
|
|
|
- case []byte:
|
|
|
- return string(vt)
|
|
|
- default:
|
|
|
- return fmt.Sprint(val.Interface())
|
|
|
- }
|
|
|
+ return reprOfValue(val)
|
|
|
}
|
|
|
|
|
|
func ValidatePtr(v *reflect.Value) error {
|
|
@@ -163,48 +126,8 @@ func doParseKeyAndOptions(field reflect.StructField, value string) (string, *fie
|
|
|
var fieldOpts fieldOptions
|
|
|
for _, segment := range options {
|
|
|
option := strings.TrimSpace(segment)
|
|
|
- switch {
|
|
|
- case option == stringOption:
|
|
|
- fieldOpts.FromString = true
|
|
|
- case strings.HasPrefix(option, optionalOption):
|
|
|
- segs := strings.Split(option, equalToken)
|
|
|
- switch len(segs) {
|
|
|
- case 1:
|
|
|
- fieldOpts.Optional = true
|
|
|
- case 2:
|
|
|
- fieldOpts.Optional = true
|
|
|
- fieldOpts.OptionalDep = segs[1]
|
|
|
- default:
|
|
|
- return "", nil, fmt.Errorf("field %s has wrong optional", field.Name)
|
|
|
- }
|
|
|
- case option == optionalOption:
|
|
|
- fieldOpts.Optional = true
|
|
|
- case strings.HasPrefix(option, optionsOption):
|
|
|
- segs := strings.Split(option, equalToken)
|
|
|
- if len(segs) != 2 {
|
|
|
- return "", nil, fmt.Errorf("field %s has wrong options", field.Name)
|
|
|
- }
|
|
|
-
|
|
|
- fieldOpts.Options = strings.Split(segs[1], optionSeparator)
|
|
|
- case strings.HasPrefix(option, defaultOption):
|
|
|
- segs := strings.Split(option, equalToken)
|
|
|
- if len(segs) != 2 {
|
|
|
- return "", nil, fmt.Errorf("field %s has wrong default option", field.Name)
|
|
|
- }
|
|
|
-
|
|
|
- fieldOpts.Default = strings.TrimSpace(segs[1])
|
|
|
- case strings.HasPrefix(option, rangeOption):
|
|
|
- segs := strings.Split(option, equalToken)
|
|
|
- if len(segs) != 2 {
|
|
|
- return "", nil, fmt.Errorf("field %s has wrong range", field.Name)
|
|
|
- }
|
|
|
-
|
|
|
- nr, err := parseNumberRange(segs[1])
|
|
|
- if err != nil {
|
|
|
- return "", nil, err
|
|
|
- }
|
|
|
-
|
|
|
- fieldOpts.Range = nr
|
|
|
+ if err := parseOption(&fieldOpts, field.Name, option); err != nil {
|
|
|
+ return "", nil, err
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -348,6 +271,95 @@ func parseNumberRange(str string) (*numberRange, error) {
|
|
|
}, nil
|
|
|
}
|
|
|
|
|
|
+func parseOption(fieldOpts *fieldOptions, fieldName string, option string) error {
|
|
|
+ switch {
|
|
|
+ case option == stringOption:
|
|
|
+ fieldOpts.FromString = true
|
|
|
+ case strings.HasPrefix(option, optionalOption):
|
|
|
+ segs := strings.Split(option, equalToken)
|
|
|
+ switch len(segs) {
|
|
|
+ case 1:
|
|
|
+ fieldOpts.Optional = true
|
|
|
+ case 2:
|
|
|
+ fieldOpts.Optional = true
|
|
|
+ fieldOpts.OptionalDep = segs[1]
|
|
|
+ default:
|
|
|
+ return fmt.Errorf("field %s has wrong optional", fieldName)
|
|
|
+ }
|
|
|
+ case option == optionalOption:
|
|
|
+ fieldOpts.Optional = true
|
|
|
+ case strings.HasPrefix(option, optionsOption):
|
|
|
+ segs := strings.Split(option, equalToken)
|
|
|
+ if len(segs) != 2 {
|
|
|
+ return fmt.Errorf("field %s has wrong options", fieldName)
|
|
|
+ }
|
|
|
+
|
|
|
+ fieldOpts.Options = strings.Split(segs[1], optionSeparator)
|
|
|
+ case strings.HasPrefix(option, defaultOption):
|
|
|
+ segs := strings.Split(option, equalToken)
|
|
|
+ if len(segs) != 2 {
|
|
|
+ return fmt.Errorf("field %s has wrong default option", fieldName)
|
|
|
+ }
|
|
|
+
|
|
|
+ fieldOpts.Default = strings.TrimSpace(segs[1])
|
|
|
+ case strings.HasPrefix(option, rangeOption):
|
|
|
+ segs := strings.Split(option, equalToken)
|
|
|
+ if len(segs) != 2 {
|
|
|
+ return fmt.Errorf("field %s has wrong range", fieldName)
|
|
|
+ }
|
|
|
+
|
|
|
+ nr, err := parseNumberRange(segs[1])
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ fieldOpts.Range = nr
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func reprOfValue(val reflect.Value) string {
|
|
|
+ switch vt := val.Interface().(type) {
|
|
|
+ case bool:
|
|
|
+ return strconv.FormatBool(vt)
|
|
|
+ case error:
|
|
|
+ return vt.Error()
|
|
|
+ case float32:
|
|
|
+ return strconv.FormatFloat(float64(vt), 'f', -1, 32)
|
|
|
+ case float64:
|
|
|
+ return strconv.FormatFloat(vt, 'f', -1, 64)
|
|
|
+ case fmt.Stringer:
|
|
|
+ return vt.String()
|
|
|
+ case int:
|
|
|
+ return strconv.Itoa(vt)
|
|
|
+ case int8:
|
|
|
+ return strconv.Itoa(int(vt))
|
|
|
+ case int16:
|
|
|
+ return strconv.Itoa(int(vt))
|
|
|
+ case int32:
|
|
|
+ return strconv.Itoa(int(vt))
|
|
|
+ case int64:
|
|
|
+ return strconv.FormatInt(vt, 10)
|
|
|
+ case string:
|
|
|
+ return vt
|
|
|
+ case uint:
|
|
|
+ return strconv.FormatUint(uint64(vt), 10)
|
|
|
+ case uint8:
|
|
|
+ return strconv.FormatUint(uint64(vt), 10)
|
|
|
+ case uint16:
|
|
|
+ return strconv.FormatUint(uint64(vt), 10)
|
|
|
+ case uint32:
|
|
|
+ return strconv.FormatUint(uint64(vt), 10)
|
|
|
+ case uint64:
|
|
|
+ return strconv.FormatUint(vt, 10)
|
|
|
+ case []byte:
|
|
|
+ return string(vt)
|
|
|
+ default:
|
|
|
+ return fmt.Sprint(val.Interface())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
func setMatchedPrimitiveValue(kind reflect.Kind, value reflect.Value, v interface{}) error {
|
|
|
switch kind {
|
|
|
case reflect.Bool:
|