Add rc.split custom operator (#4066)
### Checklist
- [x] If applicable, unit tests
- [ ] If applicable, create follow-up issues for `purchases-ios` and
hybrids
### Motivation
Port of RevenueCat/purchases-ios#7473. Rules need to target parts of
composite strings: locale subtags, product-id namespaces, version
components.
### Description
`{"rc.split": [input, separator]}` returns every field, including empty
ones, always as strings.
A `var` path cannot index the result of an expression, so a positional
field is read by wrapping the array in a one-element list so an
iteration operator rebinds the scope to it:
```json
{"some": [[{"rc.split": [{"var": "locale"}, "-"]}], {"===": [{"var": "0"}, "es"]}]}
```
`in` and the iteration operators consume the array directly. An empty
separator throws `typeMismatch` instead of splitting into characters,
matching `rc.entries` on string input.
### Notes
Stacked on #4050, whose `rc.length` the fixtures use. Seventeen fixtures
copied byte-for-byte from iOS (428 total). Kotlin's `split` treats the
separator literally, matching Swift's `components(separatedBy:)` for
separators like `"."`.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Adds a self-contained rules operator with fixture tests only; no
changes to purchase, auth, or networking paths.
>
> **Overview**
> Adds the **`rc.split`** JSON Logic operator so rules can break
composite strings (locales, product IDs, versions) into string arrays.
>
> `{"rc.split": [input, separator]}` requires exactly two string
arguments, rejects an empty separator with `typeMismatch` (aligned with
`rc.entries`), and returns an **`ArrayValue`** of **`StringValue`**
fields—including empty segments—with no numeric coercion.
**`CustomOperators`** dispatches to new **`SplitOperator`**, which uses
Kotlin’s literal `String.split`.
>
> Conformance coverage comes from **`rc_split.json`** (ported from iOS)
and the predicate fixture count guard moves **449 → 467**.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
7c8196d7440f5ac094588a861c648d1b8cee4f36. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Cursor <cursoragent@cursor.com> A
Antonio Pallares committed
9d79082c0d1812d0785680330a3180969057ee58
Parent: 8bed2af
Committed by GitHub <noreply@github.com>
on 8/25/2026, 9:58:28 AM