dredd_rs/rule/
best_first_rule.rs1use crate::rule::{EvalFn, ExecuteFn, Rule, RuleContext, RuleResult};
2
3pub struct BestFirstRule {
27 children: Vec<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 BestFirstRule {
35 pub fn new() -> Self {
37 BestFirstRule {
38 children: Vec::new(),
39 eval_fn: None,
40 pre_execute_fn: None,
41 execute_fn: None,
42 post_execute_fn: None,
43 }
44 }
45
46 pub fn set_eval_fn<F>(&mut self, f: F) -> &mut Self
48 where
49 F: Fn(&RuleContext) -> RuleResult<bool> + 'static,
50 {
51 self.eval_fn = Some(Box::new(f));
52 self
53 }
54
55 pub fn set_pre_execute_fn<F>(&mut self, f: F) -> &mut Self
57 where
58 F: Fn(&mut RuleContext) -> RuleResult<()> + 'static,
59 {
60 self.pre_execute_fn = Some(Box::new(f));
61 self
62 }
63
64 pub fn set_execute_fn<F>(&mut self, f: F) -> &mut Self
66 where
67 F: Fn(&mut RuleContext) -> RuleResult<()> + 'static,
68 {
69 self.execute_fn = Some(Box::new(f));
70 self
71 }
72
73 pub fn set_post_execute_fn<F>(&mut self, f: F) -> &mut Self
75 where
76 F: Fn(&mut RuleContext) -> RuleResult<()> + 'static,
77 {
78 self.post_execute_fn = Some(Box::new(f));
79 self
80 }
81}
82
83impl Rule for BestFirstRule {
84 fn evaluate(&self, context: &RuleContext) -> RuleResult<bool> {
85 match &self.eval_fn {
86 Some(f) => f(context),
87 None => Ok(true), }
89 }
90
91 fn execute(&mut self, context: &mut RuleContext) -> RuleResult<()> {
92 if let Some(f) = &self.pre_execute_fn {
94 f(context)?;
95 }
96
97 if let Some(f) = &self.execute_fn {
99 f(context)?;
100 }
101
102 if let Some(f) = &self.post_execute_fn {
104 f(context)?;
105 }
106
107 Ok(())
108 }
109
110 fn children(&self) -> &[Box<dyn Rule>] {
111 &self.children
112 }
113
114 fn children_mut(&mut self) -> &mut Vec<Box<dyn Rule>> {
115 &mut self.children
116 }
117
118 fn add_child(&mut self, child: Box<dyn Rule>) -> RuleResult<()> {
119 self.children.push(child);
120 Ok(())
121 }
122
123 fn fire(&mut self, context: &mut RuleContext) -> RuleResult<bool> {
125 if self.evaluate(context)? {
126 self.execute(context)?;
127
128 for child in &mut self.children {
130 if child.evaluate(context)? {
131 child.fire(context)?;
132 return Ok(true);
133 }
134 }
135
136 Ok(true)
137 } else {
138 Ok(false)
139 }
140 }
141}
142
143impl Default for BestFirstRule {
144 fn default() -> Self {
145 Self::new()
146 }
147}