diff --git a/core/mapping/unmarshaler.go b/core/mapping/unmarshaler.go index 57a3d7e8..8a9fbd61 100644 --- a/core/mapping/unmarshaler.go +++ b/core/mapping/unmarshaler.go @@ -622,7 +622,7 @@ func (u *Unmarshaler) processFieldPrimitiveWithJSONNumber(fieldType reflect.Type } if fValue > math.MaxFloat32 { - return float32OverflowError(v.String()) + return fmt.Errorf("parsing %q as float32: value out of range", v.String()) } target.SetFloat(fValue) diff --git a/core/mapping/utils.go b/core/mapping/utils.go index e00a61ea..72216bfc 100644 --- a/core/mapping/utils.go +++ b/core/mapping/utils.go @@ -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