149 lines
2.8 KiB
Go
149 lines
2.8 KiB
Go
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
|
|
}
|