dredd_rs/rule/
chain_rule.rs1use crate::rule::{EvalFn, ExecuteFn, Rule, RuleContext, RuleError, RuleResult};
2
3pub struct ChainRule {
27 child: Option<Box<dyn Rule>>,
28 eval_fn: Option<EvalFn>,
29 pre_execute_fn: Option<ExecuteFn>,
30 execute_fn: Option<ExecuteFn>,
31 post_execute_fn: Option<ExecuteFn>,
32}
33
34impl ChainRule {
35 pub fn new() -> Self {
37 ChainRule {
38 child: None,
39 eval_fn: None,
40 pre_execute_fn: None,
41 execute_fn: None,
42 post_execute_fn: None,
43 }
44 }
45
46 pub fn builder() -> ChainRuleBuilder {
48 ChainRuleBuilder::new()
49 }
50
51 pub fn set_eval_fn<F>(&mut self, f: F) -> &mut Self
53 where
54 F: Fn(&RuleContext) -> RuleResult<bool> + 'static,
55 {
56 self.eval_fn = Some(Box::new(f));
57 self
58 }
59
60 pub fn set_pre_execute_fn<F>(&mut self, f: F) -> &mut Self
62 where
63 F: Fn(&mut RuleContext) -> RuleResult<()> + 'static,
64 {
65 self.pre_execute_fn = Some(Box::new(f));
66 self
67 }
68
69 pub fn set_execute_fn<F>(&mut self, f: F) -> &mut Self
71 where
72 F: Fn(&mut RuleContext) -> RuleResult<()> + 'static,
73 {
74 self.execute_fn = Some(Box::new(f));
75 self
76 }
77
78 pub fn set_post_execute_fn<F>(&mut self, f: F) -> &mut Self
80 where
81 F: Fn(&mut RuleContext) -> RuleResult<()> + 'static,
82 {
83 self.post_execute_fn = Some(Box::new(f));
84 self
85 }
86
87 pub fn set_child(&mut self, child: Box<dyn Rule>) -> RuleResult<&mut Self> {
89 if self.child.is_some() {
90 return Err(RuleError::TooManyChildren {
91 max: 1,
92 attempted: 2,
93 });
94 }
95 self.child = Some(child);
96 Ok(self)
97 }
98}
99
100impl Rule for ChainRule {
101 fn evaluate(&self, context: &RuleContext) -> RuleResult<bool> {
102 match &self.eval_fn {
103 Some(f) => f(context),
104 None => Ok(true), }
106 }
107
108 fn execute(&mut self, context: &mut RuleContext) -> RuleResult<()> {
109 if let Some(f) = &self.pre_execute_fn {
111 f(context)?;
112 }
113
114 if let Some(f) = &self.execute_fn {
116 f(context)?;
117 }
118
119 if let Some(f) = &self.post_execute_fn {
121 f(context)?;
122 }
123
124 Ok(())
125 }
126
127 fn children(&self) -> &[Box<dyn Rule>] {
128 match &self.child {
129 Some(child) => std::slice::from_ref(child),
130 None => &[],
131 }
132 }
133
134 fn children_mut(&mut self) -> &mut Vec<Box<dyn Rule>> {
135 unimplemented!("ChainRule uses custom child execution in fire()")
138 }
139
140 fn add_child(&mut self, child: Box<dyn Rule>) -> RuleResult<()> {
141 if self.child.is_some() {
142 return Err(RuleError::TooManyChildren {
143 max: 1,
144 attempted: 2,
145 });
146 }
147 self.child = Some(child);
148 Ok(())
149 }
150
151 fn fire(&mut self, context: &mut RuleContext) -> RuleResult<bool> {
153 if self.evaluate(context)? {
154 self.execute(context)?;
155
156 if let Some(child) = &mut self.child {
158 child.fire(context)?;
159 }
160
161 Ok(true)
162 } else {
163 Ok(false)
164 }
165 }
166}
167
168impl Default for ChainRule {
169 fn default() -> Self {
170 Self::new()
171 }
172}
173
174pub struct ChainRuleBuilder {
176 rule: ChainRule,
177}
178
179impl ChainRuleBuilder {
180 pub fn new() -> Self {
182 ChainRuleBuilder {
183 rule: ChainRule::new(),
184 }
185 }
186
187 pub fn eval_fn<F>(mut self, f: F) -> Self
189 where
190 F: Fn(&RuleContext) -> RuleResult<bool> + 'static,
191 {
192 self.rule.set_eval_fn(f);
193 self
194 }
195
196 pub fn pre_execute_fn<F>(mut self, f: F) -> Self
198 where
199 F: Fn(&mut RuleContext) -> RuleResult<()> + 'static,
200 {
201 self.rule.set_pre_execute_fn(f);
202 self
203 }
204
205 pub fn execute_fn<F>(mut self, f: F) -> Self
207 where
208 F: Fn(&mut RuleContext) -> RuleResult<()> + 'static,
209 {
210 self.rule.set_execute_fn(f);
211 self
212 }
213
214 pub fn post_execute_fn<F>(mut self, f: F) -> Self
216 where
217 F: Fn(&mut RuleContext) -> RuleResult<()> + 'static,
218 {
219 self.rule.set_post_execute_fn(f);
220 self
221 }
222
223 pub fn child(mut self, child: Box<dyn Rule>) -> RuleResult<Self> {
225 self.rule.add_child(child)?;
226 Ok(self)
227 }
228
229 pub fn build(self) -> ChainRule {
231 self.rule
232 }
233}
234
235impl Default for ChainRuleBuilder {
236 fn default() -> Self {
237 Self::new()
238 }
239}