254 lines
4.6 KiB
Go
254 lines
4.6 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
|
|
}
|
|
|
|
// 类型转换后比较
|
|
return normalizeValue(a) == normalizeValue(b)
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// 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
|
|
}
|