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
+ }
0 commit comments