|
|
|
@ -30,6 +30,7 @@ const (
|
|
|
|
|
leftSquareBracket = '['
|
|
|
|
|
rightSquareBracket = ']'
|
|
|
|
|
segmentSeparator = ','
|
|
|
|
|
intSize = 32 << (^uint(0) >> 63)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
@ -42,10 +43,6 @@ var (
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type (
|
|
|
|
|
integer interface {
|
|
|
|
|
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
optionsCacheValue struct {
|
|
|
|
|
key string
|
|
|
|
|
options *fieldOptions
|
|
|
|
@ -104,38 +101,30 @@ func convertTypeFromString(kind reflect.Kind, str string) (any, error) {
|
|
|
|
|
default:
|
|
|
|
|
return false, errTypeMismatch
|
|
|
|
|
}
|
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
|
|
intValue, err := strconv.ParseInt(str, 10, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return intValue, nil
|
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
|
|
|
uintValue, err := strconv.ParseUint(str, 10, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return uintValue, nil
|
|
|
|
|
case reflect.Int:
|
|
|
|
|
return strconv.ParseInt(str, 10, intSize)
|
|
|
|
|
case reflect.Int8:
|
|
|
|
|
return strconv.ParseInt(str, 10, 8)
|
|
|
|
|
case reflect.Int16:
|
|
|
|
|
return strconv.ParseInt(str, 10, 16)
|
|
|
|
|
case reflect.Int32:
|
|
|
|
|
return strconv.ParseInt(str, 10, 32)
|
|
|
|
|
case reflect.Int64:
|
|
|
|
|
return strconv.ParseInt(str, 10, 64)
|
|
|
|
|
case reflect.Uint:
|
|
|
|
|
return strconv.ParseUint(str, 10, intSize)
|
|
|
|
|
case reflect.Uint8:
|
|
|
|
|
return strconv.ParseUint(str, 10, 8)
|
|
|
|
|
case reflect.Uint16:
|
|
|
|
|
return strconv.ParseUint(str, 10, 16)
|
|
|
|
|
case reflect.Uint32:
|
|
|
|
|
return strconv.ParseUint(str, 10, 32)
|
|
|
|
|
case reflect.Uint64:
|
|
|
|
|
return strconv.ParseUint(str, 10, 64)
|
|
|
|
|
case reflect.Float32:
|
|
|
|
|
floatValue, err := strconv.ParseFloat(str, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if floatValue > math.MaxFloat32 {
|
|
|
|
|
return 0, float32OverflowError(str)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return floatValue, nil
|
|
|
|
|
return strconv.ParseFloat(str, 32)
|
|
|
|
|
case reflect.Float64:
|
|
|
|
|
floatValue, err := strconv.ParseFloat(str, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return floatValue, nil
|
|
|
|
|
return strconv.ParseFloat(str, 64)
|
|
|
|
|
case reflect.String:
|
|
|
|
|
return str, nil
|
|
|
|
|
default:
|
|
|
|
@ -230,10 +219,6 @@ func implicitValueRequiredStruct(tag string, tp reflect.Type) (bool, error) {
|
|
|
|
|
return false, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func intOverflowError[T integer](v T, kind reflect.Kind) error {
|
|
|
|
|
return fmt.Errorf("parsing \"%d\" as %s: value out of range", v, kind.String())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func isLeftInclude(b byte) (bool, error) {
|
|
|
|
|
switch b {
|
|
|
|
|
case '[':
|
|
|
|
@ -256,10 +241,6 @@ func isRightInclude(b byte) (bool, error) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func float32OverflowError(str string) error {
|
|
|
|
|
return fmt.Errorf("parsing %q as float32: value out of range", str)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func maybeNewValue(fieldType reflect.Type, value reflect.Value) {
|
|
|
|
|
if fieldType.Kind() == reflect.Ptr && value.IsNil() {
|
|
|
|
|
value.Set(reflect.New(value.Type().Elem()))
|
|
|
|
@ -505,41 +486,15 @@ func parseSegments(val string) []string {
|
|
|
|
|
return segments
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func setIntValue(value reflect.Value, v any, min, max int64) error {
|
|
|
|
|
iv := v.(int64)
|
|
|
|
|
if iv < min || iv > max {
|
|
|
|
|
return intOverflowError(iv, value.Kind())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value.SetInt(iv)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func setMatchedPrimitiveValue(kind reflect.Kind, value reflect.Value, v any) error {
|
|
|
|
|
switch kind {
|
|
|
|
|
case reflect.Bool:
|
|
|
|
|
value.SetBool(v.(bool))
|
|
|
|
|
return nil
|
|
|
|
|
case reflect.Int: // int depends on int size, 32 or 64
|
|
|
|
|
return setIntValue(value, v, math.MinInt, math.MaxInt)
|
|
|
|
|
case reflect.Int8:
|
|
|
|
|
return setIntValue(value, v, math.MinInt8, math.MaxInt8)
|
|
|
|
|
case reflect.Int16:
|
|
|
|
|
return setIntValue(value, v, math.MinInt16, math.MaxInt16)
|
|
|
|
|
case reflect.Int32:
|
|
|
|
|
return setIntValue(value, v, math.MinInt32, math.MaxInt32)
|
|
|
|
|
case reflect.Int64:
|
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
|
|
value.SetInt(v.(int64))
|
|
|
|
|
return nil
|
|
|
|
|
case reflect.Uint: // uint depends on int size, 32 or 64
|
|
|
|
|
return setUintValue(value, v, math.MaxUint)
|
|
|
|
|
case reflect.Uint8:
|
|
|
|
|
return setUintValue(value, v, math.MaxUint8)
|
|
|
|
|
case reflect.Uint16:
|
|
|
|
|
return setUintValue(value, v, math.MaxUint16)
|
|
|
|
|
case reflect.Uint32:
|
|
|
|
|
return setUintValue(value, v, math.MaxUint32)
|
|
|
|
|
case reflect.Uint64:
|
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
|
|
|
value.SetUint(v.(uint64))
|
|
|
|
|
return nil
|
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
|
|
@ -553,16 +508,6 @@ func setMatchedPrimitiveValue(kind reflect.Kind, value reflect.Value, v any) err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func setUintValue(value reflect.Value, v any, boundary uint64) error {
|
|
|
|
|
iv := v.(uint64)
|
|
|
|
|
if iv > boundary {
|
|
|
|
|
return intOverflowError(iv, value.Kind())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value.SetUint(iv)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func setValueFromString(kind reflect.Kind, value reflect.Value, str string) error {
|
|
|
|
|
if !value.CanSet() {
|
|
|
|
|
return errValueNotSettable
|
|
|
|
|