gomog/internal/engine/operators.go

366 lines
6.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}