366 lines
6.9 KiB
Go
366 lines
6.9 KiB
Go
package engine
|
||
|
||
import (
|
||
"reflect"
|
||
"regexp"
|
||
"strconv"
|
||
"strings"
|
||
)
|
||
|
||
// compareEq 相等比较
|
||
func compareEq(a, b interface{}) bool {
|
||
if a == nil && b == nil {
|
||
return true
|
||
}
|
||
if a == nil || b == nil {
|
||
return false
|
||
}
|
||
|
||
// 对于 slice、map 等复杂类型,使用 reflect.DeepEqual
|
||
if isComplexType(a) || isComplexType(b) {
|
||
return reflect.DeepEqual(a, b)
|
||
}
|
||
|
||
// 类型转换后比较
|
||
return normalizeValue(a) == normalizeValue(b)
|
||
}
|
||
|
||
// isComplexType 检查是否是复杂类型(slice、map 等)
|
||
func isComplexType(v interface{}) bool {
|
||
switch v.(type) {
|
||
case []interface{}:
|
||
return true
|
||
case map[string]interface{}:
|
||
return true
|
||
case map[interface{}]interface{}:
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
|
||
// compareGt 大于比较
|
||
func compareGt(a, b interface{}) bool {
|
||
return compareNumbers(a, b) > 0
|
||
}
|
||
|
||
// compareGte 大于等于比较
|
||
func compareGte(a, b interface{}) bool {
|
||
return compareNumbers(a, b) >= 0
|
||
}
|
||
|
||
// compareLt 小于比较
|
||
func compareLt(a, b interface{}) bool {
|
||
return compareNumbers(a, b) < 0
|
||
}
|
||
|
||
// compareLte 小于等于比较
|
||
func compareLte(a, b interface{}) bool {
|
||
return compareNumbers(a, b) <= 0
|
||
}
|
||
|
||
// compareNumbers 比较两个数值,返回 -1/0/1
|
||
func compareNumbers(a, b interface{}) int {
|
||
numA := toFloat64(a)
|
||
numB := toFloat64(b)
|
||
|
||
if numA < numB {
|
||
return -1
|
||
} else if numA > numB {
|
||
return 1
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// toFloat64 将值转换为 float64
|
||
func toFloat64(v interface{}) float64 {
|
||
switch val := v.(type) {
|
||
case int:
|
||
return float64(val)
|
||
case int8:
|
||
return float64(val)
|
||
case int16:
|
||
return float64(val)
|
||
case int32:
|
||
return float64(val)
|
||
case int64:
|
||
return float64(val)
|
||
case uint:
|
||
return float64(val)
|
||
case uint8:
|
||
return float64(val)
|
||
case uint16:
|
||
return float64(val)
|
||
case uint32:
|
||
return float64(val)
|
||
case uint64:
|
||
return float64(val)
|
||
case float32:
|
||
return float64(val)
|
||
case float64:
|
||
return val
|
||
case string:
|
||
// 尝试解析字符串为数字
|
||
if num, err := strconv.ParseFloat(val, 64); err == nil {
|
||
return num
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// compareIn 检查值是否在数组中
|
||
func compareIn(value interface{}, operand interface{}) bool {
|
||
arr, ok := operand.([]interface{})
|
||
if !ok {
|
||
return false
|
||
}
|
||
|
||
for _, item := range arr {
|
||
if compareEq(value, item) {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// compareRegex 正则表达式匹配
|
||
func compareRegex(value interface{}, operand interface{}) bool {
|
||
str, ok := value.(string)
|
||
if !ok {
|
||
return false
|
||
}
|
||
|
||
pattern, ok := operand.(string)
|
||
if !ok {
|
||
return false
|
||
}
|
||
|
||
matched, _ := regexp.MatchString(pattern, str)
|
||
return matched
|
||
}
|
||
|
||
// compareType 类型检查
|
||
func compareType(value interface{}, operand interface{}) bool {
|
||
if value == nil {
|
||
return operand == "null"
|
||
}
|
||
|
||
var typeName string
|
||
switch reflect.TypeOf(value).Kind() {
|
||
case reflect.String:
|
||
typeName = "string"
|
||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||
typeName = "int"
|
||
case reflect.Float32, reflect.Float64:
|
||
typeName = "double"
|
||
case reflect.Bool:
|
||
typeName = "bool"
|
||
case reflect.Slice, reflect.Array:
|
||
typeName = "array"
|
||
case reflect.Map:
|
||
typeName = "object"
|
||
}
|
||
|
||
// 支持字符串或数组形式的类型检查
|
||
switch op := operand.(type) {
|
||
case string:
|
||
return typeName == op
|
||
case []interface{}:
|
||
for _, t := range op {
|
||
if ts, ok := t.(string); ok && typeName == ts {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
|
||
return false
|
||
}
|
||
|
||
// compareAll 数组包含所有指定元素
|
||
func compareAll(value interface{}, operand interface{}) bool {
|
||
arr, ok := value.([]interface{})
|
||
if !ok {
|
||
return false
|
||
}
|
||
|
||
required, ok := operand.([]interface{})
|
||
if !ok {
|
||
return false
|
||
}
|
||
|
||
for _, req := range required {
|
||
found := false
|
||
for _, item := range arr {
|
||
if compareEq(item, req) {
|
||
found = true
|
||
break
|
||
}
|
||
}
|
||
if !found {
|
||
return false
|
||
}
|
||
}
|
||
|
||
return true
|
||
}
|
||
|
||
// compareElemMatch 数组元素匹配
|
||
func compareElemMatch(value interface{}, operand interface{}) bool {
|
||
arr, ok := value.([]interface{})
|
||
if !ok {
|
||
return false
|
||
}
|
||
|
||
filter, ok := operand.(map[string]interface{})
|
||
if !ok {
|
||
return false
|
||
}
|
||
|
||
for _, item := range arr {
|
||
if itemMap, ok := item.(map[string]interface{}); ok {
|
||
if MatchFilter(itemMap, filter) {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
|
||
return false
|
||
}
|
||
|
||
// compareSize 数组大小比较
|
||
func compareSize(value interface{}, operand interface{}) bool {
|
||
arr, ok := value.([]interface{})
|
||
if !ok {
|
||
return false
|
||
}
|
||
|
||
size := 0
|
||
switch s := operand.(type) {
|
||
case int:
|
||
size = s
|
||
case int64:
|
||
size = int(s)
|
||
case float64:
|
||
size = int(s)
|
||
default:
|
||
return false
|
||
}
|
||
|
||
return len(arr) == size
|
||
}
|
||
|
||
// compareMod 模运算:value % divisor == remainder
|
||
func compareMod(value interface{}, operand interface{}) bool {
|
||
num := toFloat64(value)
|
||
|
||
var divisor, remainder float64
|
||
switch op := operand.(type) {
|
||
case []interface{}:
|
||
if len(op) != 2 {
|
||
return false
|
||
}
|
||
divisor = toFloat64(op[0])
|
||
remainder = toFloat64(op[1])
|
||
default:
|
||
return false
|
||
}
|
||
|
||
if divisor == 0 {
|
||
return false
|
||
}
|
||
|
||
// 计算模
|
||
mod := num - divisor*float64(int(num/divisor))
|
||
// 处理负数情况
|
||
if mod < 0 {
|
||
mod += divisor
|
||
}
|
||
|
||
return mod == remainder
|
||
}
|
||
|
||
// compareBitsAllClear 位运算:所有指定位都为 0
|
||
func compareBitsAllClear(value interface{}, operand interface{}) bool {
|
||
num := toInt64(value)
|
||
mask := toInt64(operand)
|
||
return (num & mask) == 0
|
||
}
|
||
|
||
// compareBitsAllSet 位运算:所有指定位都为 1
|
||
func compareBitsAllSet(value interface{}, operand interface{}) bool {
|
||
num := toInt64(value)
|
||
mask := toInt64(operand)
|
||
return (num & mask) == mask
|
||
}
|
||
|
||
// compareBitsAnyClear 位运算:任意指定位为 0
|
||
func compareBitsAnyClear(value interface{}, operand interface{}) bool {
|
||
num := toInt64(value)
|
||
mask := toInt64(operand)
|
||
return (num & mask) != mask
|
||
}
|
||
|
||
// compareBitsAnySet 位运算:任意指定位为 1
|
||
func compareBitsAnySet(value interface{}, operand interface{}) bool {
|
||
num := toInt64(value)
|
||
mask := toInt64(operand)
|
||
return (num & mask) != 0
|
||
}
|
||
|
||
// toInt64 将值转换为 int64
|
||
func toInt64(v interface{}) int64 {
|
||
switch val := v.(type) {
|
||
case int:
|
||
return int64(val)
|
||
case int8:
|
||
return int64(val)
|
||
case int16:
|
||
return int64(val)
|
||
case int32:
|
||
return int64(val)
|
||
case int64:
|
||
return val
|
||
case uint:
|
||
return int64(val)
|
||
case uint8:
|
||
return int64(val)
|
||
case uint16:
|
||
return int64(val)
|
||
case uint32:
|
||
return int64(val)
|
||
case uint64:
|
||
return int64(val)
|
||
case float32:
|
||
return int64(val)
|
||
case float64:
|
||
return int64(val)
|
||
case string:
|
||
if num, err := strconv.ParseInt(val, 10, 64); err == nil {
|
||
return num
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// normalizeValue 标准化值用于比较
|
||
func normalizeValue(v interface{}) interface{} {
|
||
if v == nil {
|
||
return nil
|
||
}
|
||
|
||
// 处理数字类型
|
||
switch val := v.(type) {
|
||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64:
|
||
return toFloat64(v)
|
||
case string:
|
||
// 尝试将字符串解析为数字
|
||
if num, err := strconv.ParseFloat(val, 64); err == nil {
|
||
return num
|
||
}
|
||
return strings.ToLower(val)
|
||
}
|
||
|
||
return v
|
||
}
|