operator + method
Composes two TestRule instances into a sequential Validation Pipeline.
This operator implements the Chain of Responsibility pattern using Atomic Composition. It allows individual, granular rules to be linked together into a singular governance unit, facilitating the construction of complex policy layers from simple, stateless blueprints.
When to use
- Policy Layering: Building complex validation structures (e.g.,
isNotNull + isNotEmpty + isEmail) without creating monolithic classes. - Developer Ergonomics: Providing a clean, readable syntax for building validation pipelines that is easier to scan than nested constructors.
- Modular Validation: Combining reusable, domain-specific rules into a single integrity gate for a specific Cell.
How it works
- Sequential Evaluation: When the resulting rule is called, the receiver (left side) is evaluated first.
- Short-Circuit Logic: If the first rule returns
false, theotherrule is never executed, and the entire operation returnsfalseimmediately. - Cumulative Integrity: The pipeline only returns
trueif both the principal rule and theotherrule satisfy their invariants. - Hybrid Convergence: The operator preserves
FutureOrsemantics. If either rule is asynchronous, the execution engine ensures the reactive wave is correctly awaited, maintaining Causal Integrity.
Non‑obvious
- Evaluation Order: Execution is strictly left-to-right. This is critical when a downstream rule depends on a type-check or null-check performed by an upstream rule.
- Structural Efficiency: Under the hood, this operator delegates to TestRule.chain, which utilizes the framework's Flyweight Strategy to minimize memory overhead for long validation chains.
- Short-Circuit Performance: By failing early, the pipeline avoids expensive validation logic (like database lookups) if a basic structural invariant has already failed.
Example
final isNotNull = TestRule<String?>((val, {host, arguments, user}) => val != null);
final isNotEmpty = TestRule<String>((val, {host, arguments, user}) => val.isNotEmpty);
final maxLength = TestRule<String>((val, {host, arguments, user}) => val.length <= 50);
// Compose into a pipeline
final validName = isNotNull + isNotEmpty + maxLength;
// Usage
final result = await validName.call('Simon'); // returns true
Parameters:
other: The Successor Gate. The next TestRule to be appended to the validation chain. Usescovariantto ensure type compatibility with the host environmentC.
Returns:
A new TestRule instance representing a Composite Validation Pipeline.
See Also:
- TestRule.chain: The underlying factory used for composite synthesis.
- TestCell: The primary engine that evaluates these combined pipelines.
Implementation
TestRule<C> operator +(covariant TestRule<C> other) {
return TestRule<C>.chain([this, other]);
}