1+ namespace xFunc . Maths . Analyzers2 ;
2+
3+ internal class ChainRuleBuilder < TExpression > :
4+ IInitialChainRuleBuilder < TExpression > ,
5+ IChainRuleBuilder < TExpression >
6+ where TExpression : IExpression
7+ {
8+ private ChainRule initialRule ;
9+ private ChainRule currentRule ;
10+
11+ public IChainRuleBuilder < TExpression > WithRule ( IRule < TExpression > rule )
12+ {
13+ initialRule = currentRule = new ChainRule ( rule ) ;
14+
15+ return this ;
16+ }
17+
18+ public IChainRuleBuilder < TExpression > WithNext ( IRule < TExpression > next )
19+ {
20+ var chain = new ChainRule ( next ) ;
21+ currentRule . SetNext ( chain ) ;
22+ currentRule = chain ;
23+
24+ return this ;
25+ }
26+
27+ public IRule GetRule ( )
28+ => initialRule . UnwrapIfEmpty ( ) ;
29+
30+ private sealed class ChainRule : IRule < TExpression >
31+ {
32+ private readonly IRule < TExpression > current ;
33+ private IRule < TExpression > ? next ;
34+
35+ public ChainRule ( IRule < TExpression > rule )
36+ => current = rule ?? throw new ArgumentNullException ( nameof ( rule ) ) ;
37+
38+ public void SetNext ( IRule < TExpression > rule )
39+ => next = rule ?? throw new ArgumentNullException ( nameof ( rule ) ) ;
40+
41+ public IRule UnwrapIfEmpty ( )
42+ => next is null ? current : this ;
43+
44+ public Result Execute ( IExpression expression , RuleContext context )
45+ {
46+ var result = current . Execute ( expression , context ) ;
47+ if ( result . IsHandled ( ) || result . IsReAnalyze ( ) )
48+ return result ;
49+
50+ if ( result . IsContinue ( ) )
51+ expression = result . Value ;
52+
53+ if ( next is not null )
54+ return next . Execute ( expression , context ) ;
55+
56+ return Result . NotHandled ( ) ;
57+ }
58+
59+ public Result Execute ( TExpression expression , RuleContext context )
60+ => Execute ( expression as IExpression , context ) ;
61+
62+ public string Name => "Chain Rule" ;
63+
64+ public string Description => "This is a chain of rules." ;
65+ }
66+ }
0 commit comments