go项目脚手架
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sorbet/pkg/is/util.go

211 lines
4.1 KiB

package is
import (
"encoding/json"
"errors"
"fmt"
"reflect"
"strconv"
"strings"
"time"
"unicode/utf8"
)
var (
ErrBadType = errors.New("bad value type")
ErrBadRange = errors.New("bad value range")
timeType = reflect.TypeOf(time.Time{})
nilType = reflect.TypeOf([]byte(nil))
)
// convert value to float64, return error on failed
func toFloat(in any) (f64 float64, err error) {
switch tVal := in.(type) {
case nil:
f64 = 0
case string:
f64, err = strconv.ParseFloat(strings.TrimSpace(tVal), 64)
case int:
f64 = float64(tVal)
case int8:
f64 = float64(tVal)
case int16:
f64 = float64(tVal)
case int32:
f64 = float64(tVal)
case int64:
f64 = float64(tVal)
case uint:
f64 = float64(tVal)
case uint8:
f64 = float64(tVal)
case uint16:
f64 = float64(tVal)
case uint32:
f64 = float64(tVal)
case uint64:
f64 = float64(tVal)
case float32:
f64 = float64(tVal)
case float64:
f64 = tVal
case time.Duration:
f64 = float64(tVal)
case json.Number:
f64, err = tVal.Float64()
default:
err = ErrBadType
}
return
}
// convert string to int64, return error on failed
func toInt64(in any) (i64 int64, err error) {
switch tVal := in.(type) {
case nil:
i64 = 0
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 json.Number:
i64, err = tVal.Int64()
default:
err = ErrBadType
}
return
}
// compString compare string, returns the first op second
func compString(first, second, op string) bool {
rs := strings.Compare(first, second)
if rs < 0 {
return op == "<" || op == "<="
} else if rs > 0 {
return op == ">" || op == ">="
} else {
return op == ">=" || op == "<=" || op == "="
}
}
func compTime(first, dstTime time.Time, op string) (ok bool) {
switch op {
case "<":
return first.Before(dstTime)
case "<=":
return first.Before(dstTime) || first.Equal(dstTime)
case ">":
return first.After(dstTime)
case ">=":
return first.After(dstTime) || first.Equal(dstTime)
case "=":
return first.Equal(dstTime)
case "!=":
return !first.Equal(dstTime)
}
return
}
func compNum[T int64 | float64 | uint64](first, second T, op string) bool {
switch op {
case "<":
return first < second
case "<=":
return first <= second
case ">":
return first > second
case ">=":
return first >= second
case "=":
return first == second
case "!=":
return first != second
}
return false
}
func compBool(first, second bool, op string) bool {
return compNum(boo2int(first), boo2int(second), op)
}
func boo2int(a bool) int64 {
if a {
return 1
} else {
return 0
}
}
// get reflect value length
func calcLength(val any) int {
v := reflect.Indirect(reflect.ValueOf(val))
// (u)int use width.
switch v.Kind() {
case reflect.String:
return len([]rune(v.String()))
case reflect.Map, reflect.Array, reflect.Chan, reflect.Slice:
return v.Len()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return len(strconv.FormatInt(int64(v.Uint()), 10))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return len(strconv.FormatInt(v.Int(), 10))
case reflect.Float32, reflect.Float64:
return len(fmt.Sprint(v.Interface()))
}
// cannot get length
return -1
}
func getLength(a any, rune bool) (int, error) {
field := reflect.ValueOf(a)
//if !field.IsValid() || field.IsNil() {
// return 0, nil
//}
switch field.Kind() {
case reflect.String:
if rune {
return utf8.RuneCountInString(field.String()), nil
}
return field.Len(), nil
case reflect.Slice, reflect.Map, reflect.Array:
return field.Len(), nil
case reflect.Ptr:
if field.Type().Elem().Kind() == reflect.Array {
// 类型声明中的长度
return field.Type().Elem().Len(), nil
}
}
return 0, ErrBadType
}