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 }