Files
purchases-ios/Sources/RulesEngine/CustomOperators/CustomOperators.swift
T
Antonio PallaresandCursor f9a42756ee Add rc.semverCompare custom operator (#7472)
Version targeting is the most common audience condition, and the built-in
< / > compare version strings lexicographically, ranking "10.0.0" below
"9.0.0".

rc.semverCompare returns -1, 0, or 1 so rules compose it with the existing
comparison operators. Precedence follows semver 2.0.0: numeric core first,
then prerelease identifiers, with build metadata excluded. Unparseable
input and inexact arity throw typeMismatch rather than reporting "equal",
which would quietly match every rule built on it.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-25 11:26:54 +02:00

51 lines
1.5 KiB
Swift

//
// CustomOperators.swift
//
// Created by Antonio Pallares.
//
import Foundation
extension RulesEngine {
/// RevenueCat-specific JSON Logic operators.
///
/// Operators here are namespaced under `rc.` so they cannot collide with a
/// future standard JSON Logic operator.
enum CustomOperators {
static func dispatch(
op operatorName: String,
args: Value,
vars: Scope
) throws -> Value {
switch operatorName {
case "rc.entries":
return try EntriesOperators.opEntries(args: args, vars: vars)
case "rc.fromEntries":
return try EntriesOperators.opFromEntries(args: args, vars: vars)
case "rc.length":
return try LengthOperator.opLength(args: args, vars: vars)
case "rc.lower":
return try CaseOperators.opLower(args: args, vars: vars)
case "rc.upper":
return try CaseOperators.opUpper(args: args, vars: vars)
case "rc.rootVar":
return try RootVarOperator.opRootVar(args: args, vars: vars)
case "rc.semverCompare":
return try SemverOperator.opSemverCompare(args: args, vars: vars)
case "rc.split":
return try SplitOperator.opSplit(args: args, vars: vars)
default:
throw EvaluationError.unsupportedOperator(name: operatorName)
}
}
}
}