mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-10 22:45:55 +05:45
* Add rc.regexReplace custom operator Co-authored-by: Cursor <cursoragent@cursor.com> * Place the replacement template divergence on the right axis The note blamed the three regex engines, but the template is parsed by each platform's own API and never reaches ICU, so this is the one part of the feature where the two devices differ rather than agreeing against Funnels. Records what each actually does with $& and with a $1 the pattern cannot supply. Co-authored-by: Cursor <cursoragent@cursor.com> * State the replacement contract without surveying the engines What a reader needs is that the replacement is taken literally; which template syntax each engine would otherwise have honoured is background that belongs with whoever authors the patterns. Co-authored-by: Cursor <cursoragent@cursor.com> * Compose rc.regexReplace with an operator that still exists The fixture proving a replaced string is usable downstream fed it to rc.length, which main has since removed. rc.upper keeps the point of the case without depending on an operator that is gone. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
65 lines
2.1 KiB
Swift
65 lines
2.1 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 {
|
|
|
|
// swiftlint:disable:next cyclomatic_complexity
|
|
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.let":
|
|
return try LetOperator.opLet(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.regexExtract":
|
|
return try RegexOperators.opRegexExtract(args: args, vars: vars)
|
|
case "rc.regexMatch":
|
|
return try RegexOperators.opRegexMatch(args: args, vars: vars)
|
|
case "rc.regexReplace":
|
|
return try RegexOperators.opRegexReplace(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.slice":
|
|
return try SliceOperator.opSlice(args: args, vars: vars)
|
|
|
|
case "rc.sortBy":
|
|
return try SortByOperator.opSortBy(args: args, vars: vars)
|
|
|
|
case "rc.split":
|
|
return try SplitOperator.opSplit(args: args, vars: vars)
|
|
|
|
default:
|
|
throw EvaluationError.unsupportedOperator(name: operatorName)
|
|
}
|
|
}
|
|
}
|
|
}
|