package utils import ( "fmt" "golang.org/x/exp/constraints" "runtime/debug" "sort" "stat/common/log" "time" ) func RecoverError(onError func(err error)) { if r := recover(); r != nil { err := fmt.Errorf("internal error: %v", r) if onError != nil { onError(err) } log.Error(fmt.Sprintf("[Panic] RecoverError err: %+v\n", r) + string(debug.Stack())) } } /*func PValue[T any](value T) *T { ret := value return &ret } */ type M map[string]interface{} func (m M) HasKey(key string) bool { if _, ok := m[key]; ok { return true } return false } type OnPage func(skip int64, limit int64) error func Abs[T constraints.Integer | constraints.Float](v T) T { if v < 0 { return -v } return v } func EnsureRange[T constraints.Ordered](value, min, max T) T { if value < min { value = min } if value > max { value = max } return value } func InRange[T constraints.Ordered](value, min, max T) bool { if value < min { return false } if value > max { return false } return true } func TimeIsBetween(t, min, max time.Time, includeEndPoint bool) bool { if includeEndPoint { return (t.Equal(min) || t.After(min)) && (t.Equal(max) || t.Before(max)) } else { return (t.Equal(min) || t.After(min)) && t.Before(max) } } func SlicePaged[T any](slice []T, chunkSize int, onPiece func(piece []T) error) error { array := SplitSlice(slice, chunkSize) for _, arr := range array { if err := onPiece(arr); err != nil { return err } } return nil } func CountPaged(totalCount int64, pageSize int64, onPage OnPage) error { pageTotal := int(totalCount / pageSize) if totalCount%pageSize != 0 { pageTotal++ } for page := 0; page < pageTotal; page++ { if err := onPage(int64(page)*pageSize, pageSize); err != nil { return err } } return nil } func SplitSlice[T any](s []T, chunkSize int) [][]T { if chunkSize <= 0 { return nil } var chunks [][]T for i := 0; i < len(s); i += chunkSize { end := i + chunkSize if end > len(s) { end = len(s) } chunks = append(chunks, s[i:end]) } return chunks } func GetSlicePageRange[T any](s []T, pageNum, pageSize int) []T { totalLen := len(s) start, end := GetPageRange(totalLen, pageNum, pageSize) return s[start:end] } func GetPageRange(totalLen, pageNum, pageSize int) (start, end int) { if pageNum < 1 { pageNum = 1 } if pageSize < 1 { pageSize = 10 } start = (pageNum - 1) * pageSize if start > totalLen { start = totalLen } end = start + pageSize if end > totalLen { end = totalLen } return } func IsSliceEqual[T constraints.Ordered](src []T, dst []T) bool { sort.Slice(src, func(i, j int) bool { return src[i] < src[j] }) sort.Slice(dst, func(i, j int) bool { return dst[i] < dst[j] }) if len(src) != len(dst) { return false } for i := range src { if src[i] != dst[i] { return false } } return true }