rattle_items_match/
machine.rs1use crate::ActualVal;
2use crate::ConditionsVal;
3use crate::ExpectedVal;
4use crate::MachineBuilder;
5use crate::MachineState;
6use crate::MatchingResult;
7use crate::RangeIncludesMaxVal;
8use crate::{Condition, Controls, MachineVal, Operator};
9
10impl<T> Default for MachineBuilder<T>
11where
12 T: std::clone::Clone,
13{
14 fn default() -> Self {
15 MachineBuilder {
16 actual: None,
17 expected: None,
18 }
19 }
20}
21
22impl<T> MachineBuilder<T>
23where
24 T: std::clone::Clone,
25{
26 pub fn build(&self) -> MachineVal<T> {
29 MachineVal {
30 actual: self.actual.clone().unwrap(),
31 expected: self.expected.clone().unwrap(),
32 }
33 }
34
35 pub fn actual<'a>(&'a mut self, item: &ActualVal<T>) -> &'a mut Self {
37 self.actual = Some(item.clone());
38 self
39 }
40 pub fn expected<'a>(&'a mut self, item: &ExpectedVal<T>) -> &'a mut Self {
42 self.expected = Some(item.clone());
43 self
44 }
45}
46
47impl<T> MachineVal<T>
48where
49 T: std::cmp::PartialEq + std::cmp::PartialOrd,
50{
51 pub fn exec(&self) -> bool {
54 let mut machine_state = MachineState::default();
55
56 for (i, act) in self.actual.get_items().iter().enumerate() {
57 machine_state.actual_index = i;
58 if machine_state.actual_index + 1 == self.actual.len() {
59 machine_state.is_final = true;
60 }
61
62 if let Some(mut exp) = self.expected.get(machine_state.expected_index) {
64 match self.matching2(&mut machine_state, act, &mut exp) {
65 MatchingResult::Matched => {
66 machine_state.expected_index += 1;
68 machine_state.matched_length_in_repeat = 0; machine_state.matched_length_in_seq = 0; }
71 MatchingResult::NotMatch => {
72 return false;
74 }
75 MatchingResult::Ongoing => {
76 }
78 }
79 } else {
80 return false;
83 }
84 }
85
86 return true;
89 }
90
91 pub fn matching2(
92 &self,
93 machine_state: &mut MachineState,
94 act: &T,
95 exp: &Controls<T>,
96 ) -> MatchingResult
97 where
98 T: std::cmp::PartialEq + std::cmp::PartialOrd,
99 {
100 match exp {
101 Controls::Once(exp) => match exp {
102 Operator::Or(any) => self.matching4_any(machine_state, act, any),
103 Operator::One(exp) => self.matching4_one(machine_state, act, exp),
104 },
105 Controls::Repeat(rep) => {
106 if rep.is_cutoff(machine_state.matched_length_in_repeat) {
107 match self.matching3_quantity(machine_state, act, &rep.op) {
109 MatchingResult::NotMatch => {
110 return MatchingResult::NotMatch;
112 }
113 MatchingResult::Matched | MatchingResult::Ongoing => {
114 machine_state.matched_length_in_repeat += 1;
115 if rep.is_cutoff(machine_state.matched_length_in_repeat) {
116 return MatchingResult::Matched;
123 } else if rep.is_success(machine_state.matched_length_in_repeat) {
124 return MatchingResult::Matched;
126 } else {
127 return MatchingResult::NotMatch;
129 }
130 }
131 }
132 } else {
133 match self.matching3_quantity(machine_state, act, &rep.op) {
134 MatchingResult::NotMatch => {
135 if rep.is_cutoff(machine_state.matched_length_in_repeat) {
136 return MatchingResult::Matched;
143 } else if rep.is_success(machine_state.matched_length_in_repeat) {
144 return MatchingResult::Matched;
151 } else {
152 return MatchingResult::NotMatch;
154 }
155 }
156 MatchingResult::Matched => {
157 machine_state.matched_length_in_repeat += 1;
158 return MatchingResult::Ongoing;
160 }
161 MatchingResult::Ongoing => {
162 machine_state.matched_length_in_repeat += 1;
163 return MatchingResult::Ongoing;
165 }
166 }
167 }
168 }
169 }
170 }
171
172 pub fn matching3_quantity(
173 &self,
174 machine_state: &mut MachineState,
175 act: &T,
176 exp: &Operator<T>,
177 ) -> MatchingResult
178 where
179 T: std::cmp::PartialEq + std::cmp::PartialOrd,
180 {
181 match exp {
182 Operator::Or(any) => self.matching4_any(machine_state, act, any),
183 Operator::One(exp) => self.matching4_one(machine_state, act, exp),
184 }
185 }
186
187 fn matching4_any(
188 &self,
189 machine_state: &mut MachineState,
190 act: &T,
191 any: &ConditionsVal<T>,
192 ) -> MatchingResult
193 where
194 T: std::cmp::PartialEq + std::cmp::PartialOrd,
195 {
196 for cnd in &any.conditions {
197 match self.matching4_el(machine_state, act, cnd) {
198 MatchingResult::Matched => return MatchingResult::Matched,
199 MatchingResult::Ongoing => return MatchingResult::Ongoing,
200 MatchingResult::NotMatch => {} }
202 }
203 return MatchingResult::NotMatch;
205 }
206 fn matching4_el(
207 &self,
208 machine_state: &mut MachineState,
209 act: &T,
210 el: &Condition<T>,
211 ) -> MatchingResult {
212 match el {
213 Condition::Pin(exa) => {
214 if *exa == *act {
215 MatchingResult::Matched
217 } else {
218 MatchingResult::NotMatch
219 }
220 }
221 Condition::RangeIncludesMax(rng) => self.matching5_range_contains_max(act, rng),
222 Condition::Seq(vec) => self.matching5_seq(machine_state, act, vec),
223 }
224 }
225 fn matching4_one(
226 &self,
227 machine_state: &mut MachineState,
228 act: &T,
229 nd: &Condition<T>,
230 ) -> MatchingResult
231 where
232 T: std::cmp::PartialEq + std::cmp::PartialOrd,
233 {
234 return self.matching4_el(machine_state, act, nd);
235 }
236 fn matching5_seq(
237 &self,
238 machine_state: &mut MachineState,
239 act: &T,
240 vec: &Vec<T>,
241 ) -> MatchingResult {
242 let result = if machine_state.matched_length_in_seq < vec.len() + 1 {
243 let el = &vec[machine_state.matched_length_in_seq];
245 if *el == *act {
246 MatchingResult::Ongoing
248 } else {
249 MatchingResult::NotMatch
251 }
252 } else if machine_state.matched_length_in_seq < vec.len() {
253 let el = &vec[machine_state.matched_length_in_seq];
255 if *el == *act {
256 MatchingResult::Matched
258 } else {
259 MatchingResult::NotMatch
261 }
262 } else {
263 panic!("(233) Out of bounds in sequence."); };
266 machine_state.matched_length_in_seq += 1;
267 return result;
268 }
269 fn matching5_range_contains_max(&self, act: &T, rng: &RangeIncludesMaxVal<T>) -> MatchingResult
270 where
271 T: std::cmp::PartialEq + std::cmp::PartialOrd,
272 {
273 if let Some(min) = &rng.min {
274 if *act < *min {
275 return MatchingResult::NotMatch;
276 }
277 }
278 if let Some(max) = &rng.max {
279 if *max < *act {
280 return MatchingResult::NotMatch;
281 }
282 }
283 return MatchingResult::Matched;
284 }
285}
286impl Default for MachineState {
314 fn default() -> Self {
315 MachineState {
316 actual_index: 0,
317 expected_index: 0,
318 is_final: false,
319 matched_length_in_repeat: 0,
320 matched_length_in_seq: 0,
321 }
322 }
323}