From a1e842ee97ef5da989b2045959771c9eae6b4aae Mon Sep 17 00:00:00 2001 From: Inhere Date: Thu, 7 Dec 2023 13:31:24 +0800 Subject: [PATCH] :recycle: up: math - update all value convert to other type func logic, support more options options: - NilAsFail default false: value is nil, will convert to zero value --- comdef/comdef.go | 3 + mathutil/convert.go | 479 ++++++++++++++++++++------------------- mathutil/convert_test.go | 95 +++++++- 3 files changed, 338 insertions(+), 239 deletions(-) diff --git a/comdef/comdef.go b/comdef/comdef.go index 54a16687a..d1e0ef238 100644 --- a/comdef/comdef.go +++ b/comdef/comdef.go @@ -9,6 +9,9 @@ type ( UnmarshalFunc func(bts []byte, ptr any) error ) +// ToTypeFunc convert value to defined type +type ToTypeFunc[T any] func(any) (T, error) + // IntCheckFunc check func type IntCheckFunc func(val int) error diff --git a/mathutil/convert.go b/mathutil/convert.go index 7700b8f1d..f9243f776 100644 --- a/mathutil/convert.go +++ b/mathutil/convert.go @@ -25,10 +25,51 @@ type ToUint64Func func(any) (uint64, error) // ToFloatFunc convert value to float type ToFloatFunc func(any) (float64, error) -// ConvOption convert option -type ConvOption struct { - NilAsZero bool // nil value convert to zero value - UserConvFn any +// ToTypeFunc convert value to defined type +type ToTypeFunc[T any] func(any) (T, error) + +// ConvOption convert options +type ConvOption[T any] struct { + // if ture: value is nil, will return convert error; + // if false(default): value is nil, will convert to zero value + NilAsFail bool + // set custom fallback convert func for not supported type. + UserConvFn ToTypeFunc[T] +} + +// NewConvOption create a new ConvOption +func NewConvOption[T any](optFns ...ConvOptionFn[T]) *ConvOption[T] { + opt := &ConvOption[T]{} + opt.WithOption(optFns...) + return opt +} + +// WithOption set convert option +func (opt *ConvOption[T]) WithOption(optFns ...ConvOptionFn[T]) { + for _, fn := range optFns { + if fn != nil { + fn(opt) + } + } +} + +// ConvOptionFn convert option func +type ConvOptionFn[T any] func(opt *ConvOption[T]) + +// WithNilAsFail set ConvOption.NilAsFail option +// +// Example: +// +// ToIntWithFunc(val, mathutil.WithNilAsFail[int]) +func WithNilAsFail[T any](opt *ConvOption[T]) { + opt.NilAsFail = true +} + +// WithUserConvFn set ConvOption.UserConvFn option +func WithUserConvFn[T any](fn ToTypeFunc[T]) ConvOptionFn[T] { + return func(opt *ConvOption[T]) { + opt.UserConvFn = fn + } } /************************************************************* @@ -36,9 +77,7 @@ type ConvOption struct { *************************************************************/ // Int convert value to int -func Int(in any) (int, error) { - return ToInt(in) -} +func Int(in any) (int, error) { return ToInt(in) } // SafeInt convert value to int, will ignore error func SafeInt(in any) int { @@ -47,12 +86,10 @@ func SafeInt(in any) int { } // QuietInt convert value to int, will ignore error -func QuietInt(in any) int { - return SafeInt(in) -} +func QuietInt(in any) int { return SafeInt(in) } -// MustInt convert value to int, will panic on error -func MustInt(in any) int { +// IntOrPanic convert value to int, will panic on error +func IntOrPanic(in any) int { val, err := ToInt(in) if err != nil { panic(err) @@ -60,19 +97,15 @@ func MustInt(in any) int { return val } -// IntOrPanic convert value to int, will panic on error -func IntOrPanic(in any) int { - return MustInt(in) -} +// MustInt convert value to int, will panic on error +func MustInt(in any) int { return IntOrPanic(in) } // IntOrDefault convert value to int, return defaultVal on failed -func IntOrDefault(in any, defVal int) int { - return IntOr(in, defVal) -} +func IntOrDefault(in any, defVal int) int { return IntOr(in, defVal) } // IntOr convert value to int, return defaultVal on failed func IntOr(in any, defVal int) int { - val, err := ToIntWithFunc(in, nil) + val, err := ToIntWith(in) if err != nil { return defVal } @@ -80,17 +113,23 @@ func IntOr(in any, defVal int) int { } // IntOrErr convert value to int, return error on failed -func IntOrErr(in any) (iVal int, err error) { - return ToIntWithFunc(in, nil) -} +func IntOrErr(in any) (int, error) { return ToIntWith(in) } // ToInt convert value to int, return error on failed -func ToInt(in any) (iVal int, err error) { - return ToIntWithFunc(in, nil) -} +func ToInt(in any) (int, error) { return ToIntWith(in) } + +// ToIntWith convert value to int, can with some option func. +// +// Example: +// +// ToIntWithFunc(val, mathutil.WithNilAsFail, mathutil.WithUserConvFn(func(in any) (int, error) { +// }) +func ToIntWith(in any, optFns ...ConvOptionFn[int]) (iVal int, err error) { + opt := NewConvOption[int](optFns...) + if !opt.NilAsFail && in == nil { + return 0, nil + } -// ToIntWithFunc convert value to int, will call usrFn on value type not supported. -func ToIntWithFunc(in any, usrFn ToIntFunc) (iVal int, err error) { switch tVal := in.(type) { case int: iVal = tVal @@ -150,11 +189,10 @@ func ToIntWithFunc(in any, usrFn ToIntFunc) (iVal int, err error) { } } default: - if usrFn != nil { - return usrFn(in) - } else { - err = comdef.ErrConvType + if opt.UserConvFn != nil { + return opt.UserConvFn(in) } + err = comdef.ErrConvType } return } @@ -174,14 +212,103 @@ func StrIntOr(s string, defVal int) int { return iVal } +/************************************************************* + * convert value to int64 + *************************************************************/ + +// Int64 convert value to int64, return error on failed +func Int64(in any) (int64, error) { return ToInt64(in) } + +// SafeInt64 convert value to int64, will ignore error +func SafeInt64(in any) int64 { + i64, _ := ToInt64With(in) + return i64 +} + +// QuietInt64 convert value to int64, will ignore error +func QuietInt64(in any) int64 { return SafeInt64(in) } + +// MustInt64 convert value to int64, will panic on error +func MustInt64(in any) int64 { + i64, err := ToInt64With(in) + if err != nil { + panic(err) + } + return i64 +} + +// Int64OrDefault convert value to int64, return default val on failed +func Int64OrDefault(in any, defVal int64) int64 { return Int64Or(in, defVal) } + +// Int64Or convert value to int64, return default val on failed +func Int64Or(in any, defVal int64) int64 { + i64, err := ToInt64With(in) + if err != nil { + return defVal + } + return i64 +} + +// ToInt64 convert value to int64, return error on failed +func ToInt64(in any) (int64, error) { return ToInt64With(in) } + +// Int64OrErr convert value to int64, return error on failed +func Int64OrErr(in any) (int64, error) { return ToInt64With(in) } + +// ToInt64With try to convert value to int64. can with some option func, more see ConvOption. +func ToInt64With(in any, optFns ...ConvOptionFn[int64]) (i64 int64, err error) { + opt := NewConvOption(optFns...) + if !opt.NilAsFail && in == nil { + return 0, nil + } + + switch tVal := in.(type) { + case string: + i64, err = strconv.ParseInt(strings.TrimSpace(tVal), 10, 0) + case int: + i64 = int64(tVal) + case int8: + i64 = int64(tVal) + case int16: + i64 = int64(tVal) + case int32: + i64 = int64(tVal) + case int64: + i64 = tVal + case uint: + i64 = int64(tVal) + case uint8: + i64 = int64(tVal) + case uint16: + i64 = int64(tVal) + case uint32: + i64 = int64(tVal) + case uint64: + i64 = int64(tVal) + case float32: + i64 = int64(tVal) + case float64: + i64 = int64(tVal) + case time.Duration: + i64 = int64(tVal) + case comdef.Int64able: // eg: json.Number + i64, err = tVal.Int64() + default: + if opt.UserConvFn != nil { + i64, err = opt.UserConvFn(in) + } else { + err = comdef.ErrConvType + } + } + return +} + /************************************************************* * convert value to uint *************************************************************/ // Uint convert any to uint, return error on failed -func Uint(in any) (uint, error) { - return ToUint(in) -} +func Uint(in any) (uint, error) { return ToUint(in) } // SafeUint convert any to uint, will ignore error func SafeUint(in any) uint { @@ -190,13 +317,11 @@ func SafeUint(in any) uint { } // QuietUint convert any to uint, will ignore error -func QuietUint(in any) uint { - return SafeUint(in) -} +func QuietUint(in any) uint { return SafeUint(in) } // MustUint convert any to uint, will panic on error func MustUint(in any) uint { - val, err := ToUintWithFunc(in, nil) + val, err := ToUintWith(in) if err != nil { panic(err) } @@ -204,13 +329,11 @@ func MustUint(in any) uint { } // UintOrDefault convert any to uint, return default val on failed -func UintOrDefault(in any, defVal uint) uint { - return UintOr(in, defVal) -} +func UintOrDefault(in any, defVal uint) uint { return UintOr(in, defVal) } // UintOr convert any to uint, return default val on failed func UintOr(in any, defVal uint) uint { - val, err := ToUintWithFunc(in, nil) + val, err := ToUintWith(in) if err != nil { return defVal } @@ -218,17 +341,18 @@ func UintOr(in any, defVal uint) uint { } // UintOrErr convert value to uint, return error on failed -func UintOrErr(in any) (uint, error) { - return ToUintWithFunc(in, nil) -} +func UintOrErr(in any) (uint, error) { return ToUintWith(in) } // ToUint convert value to uint, return error on failed -func ToUint(in any) (u64 uint, err error) { - return ToUintWithFunc(in, nil) -} +func ToUint(in any) (u64 uint, err error) { return ToUintWith(in) } + +// ToUintWith try to convert value to uint. can with some option func, more see ConvOption. +func ToUintWith(in any, optFns ...ConvOptionFn[uint]) (uVal uint, err error) { + opt := NewConvOption(optFns...) + if !opt.NilAsFail && in == nil { + return 0, nil + } -// ToUintWithFunc convert value to uint, will call usrFn on value type not supported. -func ToUintWithFunc(in any, usrFn ToUintFunc) (uVal uint, err error) { switch tVal := in.(type) { case int: uVal = uint(tVal) @@ -265,8 +389,8 @@ func ToUintWithFunc(in any, usrFn ToUintFunc) (uVal uint, err error) { u64, err = strconv.ParseUint(strings.TrimSpace(tVal), 10, 0) uVal = uint(u64) default: - if usrFn != nil { - uVal, err = usrFn(in) + if opt.UserConvFn != nil { + uVal, err = opt.UserConvFn(in) } else { err = comdef.ErrConvType } @@ -275,60 +399,55 @@ func ToUintWithFunc(in any, usrFn ToUintFunc) (uVal uint, err error) { } /************************************************************* - * convert value to uint + * convert value to uint64 *************************************************************/ -// Uint64 convert any to uint, return error on failed -func Uint64(in any) (uint64, error) { - return ToUint64(in) -} +// Uint64 convert any to uint64, return error on failed +func Uint64(in any) (uint64, error) { return ToUint64(in) } + +// QuietUint64 convert any to uint64, will ignore error +func QuietUint64(in any) uint64 { return SafeUint64(in) } -// SafeUint64 convert any to uint, will ignore error +// SafeUint64 convert any to uint64, will ignore error func SafeUint64(in any) uint64 { val, _ := ToUint64(in) return val } -// QuietUint64 convert any to uint, will ignore error -func QuietUint64(in any) uint64 { - return SafeUint64(in) -} - -// MustUint64 convert any to uint, will panic on error +// MustUint64 convert any to uint64, will panic on error func MustUint64(in any) uint64 { - val, err := ToUint64WithFunc(in, nil) + val, err := ToUint64With(in) if err != nil { panic(err) } return val } -// Uint64OrDefault convert any to uint, return default val on failed -func Uint64OrDefault(in any, defVal uint64) uint64 { - return Uint64Or(in, defVal) -} +// Uint64OrDefault convert any to uint64, return default val on failed +func Uint64OrDefault(in any, defVal uint64) uint64 { return Uint64Or(in, defVal) } -// Uint64Or convert any to uint, return default val on failed +// Uint64Or convert any to uint64, return default val on failed func Uint64Or(in any, defVal uint64) uint64 { - val, err := ToUint64WithFunc(in, nil) + val, err := ToUint64With(in) if err != nil { return defVal } return val } -// Uint64OrErr convert value to uint, return error on failed -func Uint64OrErr(in any) (uint64, error) { - return ToUint64WithFunc(in, nil) -} +// Uint64OrErr convert value to uint64, return error on failed +func Uint64OrErr(in any) (uint64, error) { return ToUint64With(in) } -// ToUint64 convert value to uint, return error on failed -func ToUint64(in any) (u64 uint64, err error) { - return ToUint64WithFunc(in, nil) -} +// ToUint64 convert value to uint64, return error on failed +func ToUint64(in any) (uint64, error) { return ToUint64With(in) } + +// ToUint64With try to convert value to uint64. can with some option func, more see ConvOption. +func ToUint64With(in any, optFns ...ConvOptionFn[uint64]) (u64 uint64, err error) { + opt := NewConvOption(optFns...) + if !opt.NilAsFail && in == nil { + return 0, nil + } -// ToUint64WithFunc convert value to uint, will call usrFn on value type not supported. -func ToUint64WithFunc(in any, usrFn ToUint64Func) (u64 uint64, err error) { switch tVal := in.(type) { case int: u64 = uint64(tVal) @@ -363,8 +482,8 @@ func ToUint64WithFunc(in any, usrFn ToUint64Func) (u64 uint64, err error) { case string: u64, err = strconv.ParseUint(strings.TrimSpace(tVal), 10, 0) default: - if usrFn != nil { - u64, err = usrFn(in) + if opt.UserConvFn != nil { + u64, err = opt.UserConvFn(in) } else { err = comdef.ErrConvType } @@ -373,124 +492,24 @@ func ToUint64WithFunc(in any, usrFn ToUint64Func) (u64 uint64, err error) { } /************************************************************* - * convert value to int64 - *************************************************************/ - -// Int64 convert value to int64, return error on failed -func Int64(in any) (int64, error) { - return ToInt64(in) -} - -// SafeInt64 convert value to int64, will ignore error -func SafeInt64(in any) int64 { - i64, _ := ToInt64WithFunc(in, nil) - return i64 -} - -// QuietInt64 convert value to int64, will ignore error -func QuietInt64(in any) int64 { - return SafeInt64(in) -} - -// MustInt64 convert value to int64, will panic on error -func MustInt64(in any) int64 { - i64, err := ToInt64WithFunc(in, nil) - if err != nil { - panic(err) - } - return i64 -} - -// Int64OrDefault convert value to int64, return default val on failed -func Int64OrDefault(in any, defVal int64) int64 { - return Int64Or(in, defVal) -} - -// Int64Or convert value to int64, return default val on failed -func Int64Or(in any, defVal int64) int64 { - i64, err := ToInt64WithFunc(in, nil) - if err != nil { - return defVal - } - return i64 -} - -// Int64OrErr convert value to int64, return error on failed -func Int64OrErr(in any) (int64, error) { - return ToInt64(in) -} - -// ToInt64 convert value to int64, return error on failed -func ToInt64(in any) (i64 int64, err error) { - return ToInt64WithFunc(in, nil) -} - -// ToInt64WithFunc convert value to int64, will call usrFn on value type not supported. -func ToInt64WithFunc(in any, usrFn ToInt64Func) (i64 int64, err error) { - switch tVal := in.(type) { - case string: - i64, err = strconv.ParseInt(strings.TrimSpace(tVal), 10, 0) - case int: - i64 = int64(tVal) - case int8: - i64 = int64(tVal) - case int16: - i64 = int64(tVal) - case int32: - i64 = int64(tVal) - case int64: - i64 = tVal - case uint: - i64 = int64(tVal) - case uint8: - i64 = int64(tVal) - case uint16: - i64 = int64(tVal) - case uint32: - i64 = int64(tVal) - case uint64: - i64 = int64(tVal) - case float32: - i64 = int64(tVal) - case float64: - i64 = int64(tVal) - case time.Duration: - i64 = int64(tVal) - case comdef.Int64able: // eg: json.Number - i64, err = tVal.Int64() - default: - if usrFn != nil { - i64, err = usrFn(in) - } else { - err = comdef.ErrConvType - } - } - return -} - -/************************************************************* - * convert value to float + * convert value to float64 *************************************************************/ // QuietFloat convert value to float64, will ignore error. alias of SafeFloat -func QuietFloat(in any) float64 { - return SafeFloat(in) -} +func QuietFloat(in any) float64 { return SafeFloat(in) } // SafeFloat convert value to float64, will ignore error func SafeFloat(in any) float64 { - val, _ := ToFloatWithFunc(in, nil) + val, _ := ToFloatWith(in) return val } // FloatOrPanic convert value to float64, will panic on error -func FloatOrPanic(in any) float64 { - return MustFloat(in) -} +func FloatOrPanic(in any) float64 { return MustFloat(in) } // MustFloat convert value to float64, will panic on error func MustFloat(in any) float64 { - val, err := ToFloatWithFunc(in, nil) + val, err := ToFloatWith(in) if err != nil { panic(err) } @@ -498,13 +517,11 @@ func MustFloat(in any) float64 { } // FloatOrDefault convert value to float64, will return default value on error -func FloatOrDefault(in any, defVal float64) float64 { - return FloatOr(in, defVal) -} +func FloatOrDefault(in any, defVal float64) float64 { return FloatOr(in, defVal) } // FloatOr convert value to float64, will return default value on error func FloatOr(in any, defVal float64) float64 { - val, err := ToFloatWithFunc(in, nil) + val, err := ToFloatWith(in) if err != nil { return defVal } @@ -512,22 +529,21 @@ func FloatOr(in any, defVal float64) float64 { } // Float convert value to float64, return error on failed -func Float(in any) (float64, error) { - return ToFloatWithFunc(in, nil) -} +func Float(in any) (float64, error) { return ToFloatWith(in) } // FloatOrErr convert value to float64, return error on failed -func FloatOrErr(in any) (float64, error) { - return ToFloatWithFunc(in, nil) -} +func FloatOrErr(in any) (float64, error) { return ToFloatWith(in) } // ToFloat convert value to float64, return error on failed -func ToFloat(in any) (f64 float64, err error) { - return ToFloatWithFunc(in, nil) -} +func ToFloat(in any) (float64, error) { return ToFloatWith(in) } + +// ToFloatWith try to convert value to float64. can with some option func, more see ConvOption. +func ToFloatWith(in any, optFns ...ConvOptionFn[float64]) (f64 float64, err error) { + opt := NewConvOption(optFns...) + if !opt.NilAsFail && in == nil { + return 0, nil + } -// ToFloatWithFunc convert value to float64, will call usrFn if value type not supported. -func ToFloatWithFunc(in any, usrFn ToFloatFunc) (f64 float64, err error) { switch tVal := in.(type) { case string: f64, err = strconv.ParseFloat(strings.TrimSpace(tVal), 64) @@ -560,8 +576,8 @@ func ToFloatWithFunc(in any, usrFn ToFloatFunc) (f64 float64, err error) { case comdef.Float64able: // eg: json.Number f64, err = tVal.Float64() default: - if usrFn != nil { - f64, err = usrFn(in) + if opt.UserConvFn != nil { + f64, err = opt.UserConvFn(in) } else { err = comdef.ErrConvType } @@ -575,7 +591,7 @@ func ToFloatWithFunc(in any, usrFn ToFloatFunc) (f64 float64, err error) { // MustString convert intX/floatX value to string, will panic on error func MustString(val any) string { - str, err := ToStringWithFunc(val, nil) + str, err := ToStringWith(val) if err != nil { panic(err) } @@ -586,13 +602,11 @@ func MustString(val any) string { func StringOrPanic(val any) string { return MustString(val) } // StringOrDefault convert intX/floatX value to string, will return default value on error -func StringOrDefault(val any, defVal string) string { - return StringOr(val, defVal) -} +func StringOrDefault(val any, defVal string) string { return StringOr(val, defVal) } // StringOr convert intX/floatX value to string, will return default value on error func StringOr(val any, defVal string) string { - str, err := ToStringWithFunc(val, nil) + str, err := ToStringWith(val) if err != nil { return defVal } @@ -600,19 +614,13 @@ func StringOr(val any, defVal string) string { } // ToString convert intX/floatX value to string, return error on failed -func ToString(val any) (string, error) { - return ToStringWithFunc(val, nil) -} +func ToString(val any) (string, error) { return ToStringWith(val) } // StringOrErr convert intX/floatX value to string, return error on failed -func StringOrErr(val any) (string, error) { - return ToStringWithFunc(val, nil) -} +func StringOrErr(val any) (string, error) { return ToStringWith(val) } // QuietString convert intX/floatX value to string, other type convert by fmt.Sprint -func QuietString(val any) string { - return SafeString(val) -} +func QuietString(val any) string { return SafeString(val) } // String convert intX/floatX value to string, other type convert by fmt.Sprint func String(val any) string { @@ -630,24 +638,23 @@ func SafeString(val any) string { // // if defaultAsErr is False, will use fmt.Sprint convert other type func TryToString(val any, defaultAsErr bool) (str string, err error) { - var usrFn comdef.ToStringFunc + var optFn ConvOptionFn[string] if !defaultAsErr { - usrFn = func(v any) (string, error) { - if val == nil { - return "", nil - } - return fmt.Sprint(v), nil - } + optFn = WithUserConvFn(func(a any) (string, error) { + return fmt.Sprint(a), nil + }) } - - return ToStringWithFunc(val, usrFn) + return ToStringWith(val, optFn) } -// ToStringWithFunc try convert intX/floatX value to string, will call usrFn if value type not supported. -// -// if defaultAsErr is False, will use fmt.Sprint convert other type -func ToStringWithFunc(val any, usrFn comdef.ToStringFunc) (str string, err error) { - switch value := val.(type) { +// ToStringWith try to convert value to string. can with some option func, more see ConvOption. +func ToStringWith(in any, optFns ...ConvOptionFn[string]) (str string, err error) { + opt := NewConvOption(optFns...) + if !opt.NilAsFail && in == nil { + return "", nil + } + + switch value := in.(type) { case int: str = strconv.Itoa(value) case int8: @@ -679,8 +686,8 @@ func ToStringWithFunc(val any, usrFn comdef.ToStringFunc) (str string, err error case fmt.Stringer: str = value.String() default: - if usrFn != nil { - str, err = usrFn(val) + if opt.UserConvFn != nil { + str, err = opt.UserConvFn(in) } else { err = comdef.ErrConvType } diff --git a/mathutil/convert_test.go b/mathutil/convert_test.go index 5c3c7fa6b..bd018e621 100644 --- a/mathutil/convert_test.go +++ b/mathutil/convert_test.go @@ -11,6 +11,92 @@ import ( "github.com/gookit/goutil/testutil/assert" ) +func TestWithUserConvFn(t *testing.T) { + is := assert.New(t) + in := []int{1} + + // to int + iv, err := mathutil.ToIntWith(in, mathutil.WithUserConvFn(func(v any) (int, error) { + return 2, nil + })) + is.NoErr(err) + is.Eq(2, iv) + + // to int64 + i64, err := mathutil.ToInt64With(in, mathutil.WithUserConvFn(func(v any) (int64, error) { + return 2, nil + })) + is.NoErr(err) + is.Eq(int64(2), i64) + + // to uint + u, err := mathutil.ToUintWith(in, mathutil.WithUserConvFn(func(v any) (uint, error) { + return 2, nil + })) + is.NoErr(err) + is.Eq(uint(2), u) + + // to uint64 + u64, err := mathutil.ToUint64With(in, mathutil.WithUserConvFn(func(v any) (uint64, error) { + return 2, nil + })) + is.NoErr(err) + is.Eq(uint64(2), u64) + + // to float + f, err := mathutil.ToFloatWith(in, mathutil.WithUserConvFn(func(v any) (float64, error) { + return 2, nil + })) + is.NoErr(err) + is.Eq(2.0, f) + + // to string + s, err := mathutil.ToStringWith(in, mathutil.WithUserConvFn(func(v any) (string, error) { + return "2", nil + })) + is.NoErr(err) + is.Eq("2", s) +} + +func TestWithNilAsFail(t *testing.T) { + var err error + is := assert.New(t) + + var iv int + iv, err = mathutil.ToIntWith(nil) + is.NoErr(err) + is.Eq(0, iv) + iv, err = mathutil.ToIntWith(nil, mathutil.WithNilAsFail[int]) + is.Err(err) + is.Eq(0, iv) + + var i64 int64 + i64, err = mathutil.ToInt64With(nil) + is.NoErr(err) + is.Eq(int64(0), i64) + i64, err = mathutil.ToInt64With(nil, mathutil.WithNilAsFail[int64]) + is.Err(err) + is.Eq(int64(0), i64) + + // to uint + _, err = mathutil.ToUint(nil) + is.NoErr(err) + _, err = mathutil.ToUintWith(nil, mathutil.WithNilAsFail[uint]) + is.Err(err) + + // to uint64 + _, err = mathutil.ToUint64(nil) + is.NoErr(err) + _, err = mathutil.ToUint64With(nil, mathutil.WithNilAsFail[uint64]) + is.Err(err) + + // to float + _, err = mathutil.Float(nil) + is.NoErr(err) + _, err = mathutil.ToFloatWith(nil, mathutil.WithNilAsFail[float64]) + is.Err(err) +} + func TestToInt(t *testing.T) { is := assert.New(t) @@ -49,7 +135,7 @@ func TestToInt(t *testing.T) { is.Eq(-2, intVal) _, err = mathutil.ToInt(nil) - is.Err(err) + is.NoErr(err) intVal, err = mathutil.IntOrErr("-2") is.Nil(err) @@ -157,6 +243,9 @@ func TestToInt(t *testing.T) { is.Nil(err) is.Eq(int64(-2), i64Val) + _, err = mathutil.ToInt64(nil) + is.NoErr(err) + for _, in := range tests { is.Eq(int64(2), mathutil.MustInt64(in)) } @@ -269,9 +358,9 @@ func TestToFloat(t *testing.T) { is.Eq(-123.5, fltVal) // ToFloatWithFunc - _, err = mathutil.ToFloatWithFunc([]int{2}, func(v any) (float64, error) { + _, err = mathutil.ToFloatWith([]int{2}, mathutil.WithUserConvFn(func(v any) (float64, error) { return 0, errors.New("invalid") - }) + })) is.ErrMsg(err, "invalid") }