utils/type.go (349 lines of code) (raw):
package utils
import (
"encoding/json"
"math"
"reflect"
"strconv"
"strings"
)
func ToInt(i interface{}, defaultVal int) int {
switch value := i.(type) {
case int:
return value
case float64:
return int(value)
case uint:
return int(value)
case int32:
return int(value)
case int64:
return int(value)
case string:
if val, err := strconv.Atoi(value); err == nil {
return val
} else {
return defaultVal
}
case json.Number:
if val, err := value.Int64(); err == nil {
return int(val)
} else {
return defaultVal
}
default:
return defaultVal
}
}
func ToFloat(i interface{}, defaultVal float64) float64 {
switch value := i.(type) {
case float64:
return value
case int:
return float64(value)
case int32:
return float64(value)
case int64:
return float64(value)
case uint32:
return float64(value)
case uint:
return float64(value)
case string:
if f, err := strconv.ParseFloat(value, 64); err == nil {
return f
} else {
return defaultVal
}
default:
return defaultVal
}
}
func ToFloat32(i interface{}, defaultVal float32) float32 {
switch value := i.(type) {
case float32:
return value
case float64:
return float32(value)
case int:
return float32(value)
case int32:
return float32(value)
case int64:
return float32(value)
case uint32:
return float32(value)
case uint:
return float32(value)
case string:
if f, err := strconv.ParseFloat(value, 64); err == nil {
return float32(f)
} else {
return defaultVal
}
default:
return defaultVal
}
}
func ToInt64(i interface{}, defaultVal int64) int64 {
switch value := i.(type) {
case int:
return int64(value)
case float64:
return int64(value)
case uint:
return int64(value)
case int32:
return int64(value)
case int64:
return value
case string:
if val, err := strconv.ParseInt(value, 10, 64); err == nil {
return val
} else {
return defaultVal
}
default:
return defaultVal
}
}
func ToString(i interface{}, defaultVal string) string {
switch value := i.(type) {
case int:
return strconv.Itoa(value)
case float64:
return strconv.FormatFloat(value, 'f', -1, 64)
case float32:
return strconv.FormatFloat(float64(value), 'f', -1, 64)
case int32:
return strconv.Itoa(int(value))
case uint32:
return strconv.Itoa(int(value))
case int64:
return strconv.FormatInt(value, 10)
case string:
return value
case json.Number:
return value.String()
default:
return defaultVal
}
}
func ToBool(i interface{}, defaultVal bool) bool {
switch value := i.(type) {
case bool:
return value
case int:
return value > 0
case int32:
return value > 0
case int64:
return value > 0
case string:
v := strings.ToLower(value)
if v == "false" || v == "" || v == "f" || v == "off" {
return false
} else if v == "true" || v == "t" || v == "on" {
return true
} else {
return false
}
default:
return defaultVal
}
}
func Equal(l interface{}, r interface{}) bool {
switch value := l.(type) {
case int:
return value == ToInt(r, math.MinInt32)
case float32:
return float64(value) == ToFloat(r, math.MaxFloat64)
case float64:
return value == ToFloat(r, math.MaxFloat64)
case uint:
return int(value) == ToInt(r, math.MinInt32)
case int32:
return int(value) == ToInt(r, math.MinInt32)
case int64:
return value == ToInt64(r, math.MinInt64)
case string:
return value == ToString(r, "")
case json.Number:
return value.String() == ToString(r, "")
default:
return false
}
}
func NotEqual(l interface{}, r interface{}) bool {
return !Equal(l, r)
}
func Greater(l interface{}, r interface{}) bool {
switch value := l.(type) {
case int:
return value > ToInt(r, math.MinInt32)
case float32:
return float64(value) > ToFloat(r, math.MaxFloat64)
case float64:
return value > ToFloat(r, math.MaxFloat64)
case uint:
return int(value) > ToInt(r, math.MinInt32)
case int32:
return int(value) > ToInt(r, math.MinInt32)
case int64:
return value > ToInt64(r, math.MinInt64)
case string:
return value > ToString(r, "")
case json.Number:
return value.String() > ToString(r, "")
default:
return false
}
}
func GreaterEqual(l interface{}, r interface{}) bool {
switch value := l.(type) {
case int:
return value >= ToInt(r, math.MinInt32)
case float32:
return float64(value) >= ToFloat(r, math.MaxFloat64)
case float64:
return value >= ToFloat(r, math.MaxFloat64)
case uint:
return int(value) >= ToInt(r, math.MinInt32)
case int32:
return int(value) >= ToInt(r, math.MinInt32)
case int64:
return value >= ToInt64(r, math.MinInt64)
case string:
return value >= ToString(r, "")
case json.Number:
return value.String() >= ToString(r, "")
default:
return false
}
}
func Less(l interface{}, r interface{}) bool {
return !GreaterEqual(l, r)
}
func LessEqual(l interface{}, r interface{}) bool {
return !Greater(l, r)
}
func In(l interface{}, r interface{}) bool {
values := ToString(r, "")
values = strings.Trim(values, "()")
elements := strings.Split(values, ",")
for _, element := range elements {
if Equal(l, element) {
return true
}
element = strings.Trim(element, " '\"")
if Equal(l, element) {
return true
}
}
return false
}
func Contains(leftList []interface{}, rightList []interface{}) bool {
for _, left := range leftList {
for _, right := range rightList {
if Equal(left, right) {
return true
}
}
}
return false
}
func StringContains(leftList []string, rightList []string) bool {
for _, left := range leftList {
for _, right := range rightList {
if Equal(left, right) {
return true
}
}
}
return false
}
func IntContains(leftList []int, rightList []int) bool {
for _, left := range leftList {
for _, right := range rightList {
if Equal(left, right) {
return true
}
}
}
return false
}
func IsNil(i interface{}) bool {
if i == nil {
return true
}
switch reflect.TypeOf(i).Kind() {
case reflect.Ptr, reflect.Map, reflect.Array, reflect.Chan, reflect.Slice:
return reflect.ValueOf(i).IsNil()
}
return false
}
func ToIntArray(values interface{}) (ret []int) {
switch vals := values.(type) {
case []any:
for _, v := range vals {
ret = append(ret, ToInt(v, 0))
}
case []int:
return vals
case []int32:
for _, v := range vals {
ret = append(ret, int(v))
}
case []int64:
for _, v := range vals {
ret = append(ret, int(v))
}
case []string:
for _, v := range vals {
ret = append(ret, ToInt(v, 0))
}
}
return
}
func ToStringArray(values interface{}) (ret []string) {
switch vals := values.(type) {
case []any:
for _, v := range vals {
val := ToString(v, "")
if val != "" {
ret = append(ret, val)
}
}
case []string:
return vals
case []int:
for _, v := range vals {
val := ToString(v, "")
if val != "" {
ret = append(ret, val)
}
}
case []int32:
for _, v := range vals {
val := ToString(v, "")
if val != "" {
ret = append(ret, val)
}
}
case []int64:
for _, v := range vals {
val := ToString(v, "")
if val != "" {
ret = append(ret, val)
}
}
}
return
}
// IndexOfArray returns the index of the first occurrence of val in arrs, or -1 if not present.
func IndexOfArray[T comparable](arrs []T, val T) int {
for idx, v := range arrs {
if v == val {
return idx
}
}
return -1
}