diff --git a/conv_test.go b/conv_test.go index 1012ee127..bb0114cc1 100644 --- a/conv_test.go +++ b/conv_test.go @@ -40,11 +40,11 @@ func TestToInt(t *testing.T) { // To int iVal, err := goutil.ToInt("2") is.Nil(err) - is.Eq(int(2), iVal) + is.Eq(2, iVal) iVal = goutil.Int("-2") is.Nil(err) - is.Eq(int(-2), iVal) + is.Eq(-2, iVal) // To int64 i64Val, err := goutil.ToInt64("2") diff --git a/internal/checkfn/check.go b/internal/checkfn/check.go index 1dcd1ae6d..cb0cd5957 100644 --- a/internal/checkfn/check.go +++ b/internal/checkfn/check.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "reflect" + "regexp" "strings" ) @@ -116,3 +117,9 @@ func StringsContains(ss []string, s string) bool { } return false } + +// check is number: int or float +var numReg = regexp.MustCompile(`^[-+]?\d*\.?\d+$`) + +// IsNumeric returns true if the given string is a numeric, otherwise false. +func IsNumeric(s string) bool { return numReg.MatchString(s) } diff --git a/mathutil/convert.go b/mathutil/convert.go index 0d80d330b..cbedf90f6 100644 --- a/mathutil/convert.go +++ b/mathutil/convert.go @@ -192,10 +192,12 @@ func ToIntWith(in any, optFns ...ConvOptionFn[int]) (iVal int, err error) { iVal = int(tVal) } case string: - if iVal, err = strconv.Atoi(strings.TrimSpace(tVal)); err != nil { - // handle the case where the string might be a float + sVal := strings.TrimSpace(tVal) + iVal, err = strconv.Atoi(sVal) + // handle the case where the string might be a float + if err != nil && checkfn.IsNumeric(sVal) { var floatVal float64 - if floatVal, err = strconv.ParseFloat(strings.TrimSpace(tVal), 64); err == nil { + if floatVal, err = strconv.ParseFloat(sVal, 64); err == nil { iVal = int(math.Round(floatVal)) err = nil } @@ -294,7 +296,16 @@ func ToInt64With(in any, optFns ...ConvOptionFn[int64]) (i64 int64, err error) { switch tVal := in.(type) { case string: - i64, err = strconv.ParseInt(strings.TrimSpace(tVal), 10, 0) + sVal := strings.TrimSpace(tVal) + i64, err = strconv.ParseInt(sVal, 10, 0) + // handle the case where the string might be a float + if err != nil && checkfn.IsNumeric(sVal) { + var floatVal float64 + if floatVal, err = strconv.ParseFloat(sVal, 64); err == nil { + i64 = int64(math.Round(floatVal)) + err = nil + } + } case int: i64 = int64(tVal) case int8: diff --git a/mathutil/convert_test.go b/mathutil/convert_test.go index 691bab01e..9575dad8e 100644 --- a/mathutil/convert_test.go +++ b/mathutil/convert_test.go @@ -241,6 +241,7 @@ func TestToInt(t *testing.T) { is.Eq(-2, intVal) is.Eq(0, mathutil.SafeInt(nil)) + is.Eq(2, mathutil.SafeInt("2.3")) is.Eq(-2, mathutil.MustInt("-2")) is.Eq(-2, mathutil.IntOrPanic("-2")) is.Eq(2, mathutil.IntOrDefault("invalid", 2)) @@ -353,6 +354,7 @@ func TestToInt(t *testing.T) { is.Eq(int64(0), mathutil.SafeInt64(in)) } + is.Eq(int64(2), mathutil.SafeInt64("2.3")) is.Eq(int64(0), mathutil.QuietInt64(nil)) is.Eq(int64(2), mathutil.Int64OrDefault("invalid", 2)) is.Panics(func() {