package run import ( "encoding/json" "fmt" "reflect" "strings" ) func matchCondition(raw json.RawMessage, answers map[string]interface{}) (bool, error) { if len(raw) == 0 || string(raw) == "{}" || string(raw) == "null" { return true, nil } var rule map[string]interface{} if err := json.Unmarshal(raw, &rule); err != nil { return false, err } if all, ok := rule["all"].([]interface{}); ok { for _, item := range all { object, ok := item.(map[string]interface{}) if !ok { return false, fmt.Errorf("invalid all condition") } matched, err := matchRule(object, answers) if err != nil || !matched { return false, err } } return true, nil } if any, ok := rule["any"].([]interface{}); ok { for _, item := range any { object, ok := item.(map[string]interface{}) if !ok { continue } matched, err := matchRule(object, answers) if err != nil { return false, err } if matched { return true, nil } } return false, nil } return matchRule(rule, answers) } func matchRule(rule map[string]interface{}, answers map[string]interface{}) (bool, error) { field, _ := rule["field"].(string) operator, _ := rule["operator"].(string) if field == "" || operator == "" { return false, fmt.Errorf("condition field and operator are required") } actual, exists := answers[field] expected := rule["value"] switch operator { case "exists": return exists && actual != nil && fmt.Sprint(actual) != "", nil case "not_exists": return !exists || actual == nil || fmt.Sprint(actual) == "", nil case "equals": return reflect.DeepEqual(normalizeValue(actual), normalizeValue(expected)), nil case "not_equals": return !reflect.DeepEqual(normalizeValue(actual), normalizeValue(expected)), nil case "contains": return strings.Contains(strings.ToLower(fmt.Sprint(actual)), strings.ToLower(fmt.Sprint(expected))), nil case "greater_than", "less_than": left, leftOK := toFloat(actual) right, rightOK := toFloat(expected) if !leftOK || !rightOK { return false, nil } if operator == "greater_than" { return left > right, nil } return left < right, nil case "in": values, ok := expected.([]interface{}) if !ok { return false, nil } for _, value := range values { if reflect.DeepEqual(normalizeValue(actual), normalizeValue(value)) { return true, nil } } return false, nil default: return false, fmt.Errorf("unsupported operator: %s", operator) } } func normalizeValue(value interface{}) interface{} { switch typed := value.(type) { case json.Number: if number, err := typed.Float64(); err == nil { return number } case int: return float64(typed) case int64: return float64(typed) case uint64: return float64(typed) } return value } func toFloat(value interface{}) (float64, bool) { switch typed := value.(type) { case float64: return typed, true case float32: return float64(typed), true case int: return float64(typed), true case int64: return float64(typed), true case uint64: return float64(typed), true case json.Number: result, err := typed.Float64() return result, err == nil default: return 0, false } }