1use crate::rules::{Head, Instruction, InstructionMut, Rule, Tail};
7use rstm_state::{RawState, State};
8
9pub trait RawRuleset<Q, A>
12where
13 Q: RawState,
14{
15 type Rule: Instruction<Q, A>;
16
17 private! {}
18
19 fn len(&self) -> usize;
20
21 fn is_empty(&self) -> bool {
22 self.len() == 0
23 }
24}
25
26pub trait Ruleset<Q, A>: RawRuleset<Q, A>
27where
28 Q: RawState,
29 Self::Rule: Instruction<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
30{
31
32 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>>;
33
34 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>>;
35
36 fn find_head(&self, Head { state, symbol }: Head<&Q, &A>) -> Option<&Tail<Q, A>> {
37 self.find_tail(state, symbol)
38 }
39}
40
41pub trait RuleSetMut<Q, A>: RawRuleset<Q, A>
42where
43 Q: RawState,
44 Self::Rule: Instruction<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
45{
46 fn get_mut(&mut self, head: &Head<Q, A>) -> Option<&mut Tail<Q, A>>;
47}
48impl<R, I, Q, A> RawRuleset<Q, A> for &R
53where
54 I: Instruction<Q, A>,
55 Q: RawState,
56 R: RawRuleset<Q, A, Rule = I>,
57{
58 type Rule = R::Rule;
59
60 seal! {}
61
62 fn len(&self) -> usize {
63 (*self).len()
64 }
65}
66
67macro_rules! get_tail {
68 ($iter:expr, $head:expr) => {
69 $iter.find_map(|i| {
70 if i.head().state() == $head.state() && i.head().symbol() == $head.symbol() {
71 Some(i.tail())
72 } else {
73 None
74 }
75 })
76 };
77}
78
79macro_rules! find_tail {
80 ($iter:expr, ($state:expr, $sym:expr)) => {
81 $iter.find_map(|i| {
82 if i.head().state().view() == $state && i.head().symbol() == $sym {
83 Some(i.tail())
84 } else {
85 None
86 }
87 })
88 };
89}
90
91impl<I, Q, A> RawRuleset<Q, A> for [I]
92where
93 Q: RawState,
94 I: Instruction<Q, A>,
95{
96 type Rule = I;
97
98 seal! {}
99
100 fn len(&self) -> usize {
101 <[I]>::len(self)
102 }
103
104 fn is_empty(&self) -> bool {
105 <[I]>::is_empty(self)
106 }
107}
108
109impl<I, Q, A> Ruleset<Q, A> for [I]
110where
111 Q: RawState + PartialEq,
112 A: PartialEq,
113 I: Instruction<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
114{
115 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
116 get_tail!(self.iter(), head)
117 }
118
119 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
120 find_tail!(self.iter(), (state, sym))
121 }
122}
123impl<I, Q, A> RawRuleset<Q, A> for &[I]
124where
125 Q: RawState,
126 I: Instruction<Q, A>,
127{
128 type Rule = I;
129
130 seal! {}
131
132 fn len(&self) -> usize {
133 <[I]>::len(self)
134 }
135
136 fn is_empty(&self) -> bool {
137 <[I]>::is_empty(self)
138 }
139}
140
141impl<I, Q, A> Ruleset<Q, A> for &[I]
142where
143 Q: RawState + PartialEq,
144 A: PartialEq,
145 I: Instruction<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
146{
147 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
148 get_tail!(self.iter(), head)
149 }
150
151 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
152 find_tail!(self.iter(), (state, sym))
153 }
154}
155
156impl<I, Q, A> RawRuleset<Q, A> for &mut [I]
157where
158 Q: RawState,
159 I: Instruction<Q, A>,
160{
161 type Rule = I;
162
163 seal! {}
164
165 fn len(&self) -> usize {
166 <[I]>::len(self)
167 }
168
169 fn is_empty(&self) -> bool {
170 <[I]>::is_empty(self)
171 }
172}
173
174impl<I, Q, A> Ruleset<Q, A> for &mut [I]
175where
176 Q: RawState + PartialEq,
177 A: PartialEq,
178 I: Instruction<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
179{
180 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
181 get_tail!(self.iter(), head)
182 }
183
184 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
185 find_tail!(self.iter(), (state, sym))
186 }
187}
188
189impl<I, Q, A> RuleSetMut<Q, A> for &mut [I]
190where
191 Q: RawState + PartialEq,
192 A: PartialEq,
193 I: InstructionMut<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
194{
195 fn get_mut(&mut self, head: &Head<Q, A>) -> Option<&mut Tail<Q, A>> {
196 self.iter_mut().find_map(|i| {
197 if i.head() == head {
198 Some(i.tail_mut())
199 } else {
200 None
201 }
202 })
203 }
204}
205
206impl<const N: usize, I, Q, A> RawRuleset<Q, A> for [I; N]
207where
208 Q: RawState,
209 I: Instruction<Q, A>,
210{
211 type Rule = I;
212
213 seal! {}
214
215 fn len(&self) -> usize {
216 <[I]>::len(self)
217 }
218
219 fn is_empty(&self) -> bool {
220 <[I]>::is_empty(self)
221 }
222}
223
224impl<const N: usize, I, Q, A> Ruleset<Q, A> for [I; N]
225where
226 Q: RawState + PartialEq,
227 A: PartialEq,
228 I: Instruction<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
229{
230 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
231 get_tail!(self.iter(), head)
232 }
233
234 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
235 find_tail!(self.iter(), (state, sym))
236 }
237}
238
239#[cfg(feature = "alloc")]
240mod impl_alloc {
241 use super::{RawRuleset, Ruleset};
242 use crate::{Head, Instruction, Rule, Tail};
243 use alloc::collections::{BTreeMap, BTreeSet};
244 use alloc::vec::Vec;
245 use rstm_state::{RawState, State};
246
247 impl<I, Q, A> RawRuleset<Q, A> for Vec<I>
248 where
249 Q: RawState,
250 I: Instruction<Q, A>,
251 {
252 type Rule = I;
253
254 seal! {}
255
256 fn len(&self) -> usize {
257 <Vec<I>>::len(self)
258 }
259
260 fn is_empty(&self) -> bool {
261 <Vec<I>>::is_empty(self)
262 }
263 }
264
265 impl<I, Q, A> Ruleset<Q, A> for Vec<I>
266 where
267 Q: RawState + PartialEq,
268 A: PartialEq,
269 I: Instruction<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
270 {
271 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
272 get_tail!(self.iter(), head)
273 }
274
275 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
276 find_tail!(self.iter(), (state, sym))
277 }
278 }
279
280 impl<I, Q, A> RawRuleset<Q, A> for BTreeSet<I>
281 where
282 Q: RawState,
283 I: Instruction<Q, A>,
284 {
285 type Rule = I;
286
287 seal! {}
288
289 fn len(&self) -> usize {
290 <BTreeSet<I>>::len(self)
291 }
292
293 fn is_empty(&self) -> bool {
294 <BTreeSet<I>>::is_empty(self)
295 }
296 }
297
298 impl<I, Q, A> Ruleset<Q, A> for BTreeSet<I>
299 where
300 Q: RawState + PartialEq,
301 A: PartialEq,
302 I: Instruction<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
303 {
304 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
305 get_tail!(self.iter(), head)
306 }
307
308 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
309 find_tail!(self.iter(), (state, sym))
310 }
311 }
312
313 impl<Q, A> RawRuleset<Q, A> for BTreeMap<Head<Q, A>, Tail<Q, A>>
314 where
315 Q: RawState + Ord,
316 A: Ord,
317 {
318 type Rule = Rule<Q, A>;
319
320 seal! {}
321
322 fn len(&self) -> usize {
323 <BTreeMap<Head<Q, A>, Tail<Q, A>>>::len(self)
324 }
325
326 fn is_empty(&self) -> bool {
327 <BTreeMap<Head<Q, A>, Tail<Q, A>>>::is_empty(self)
328 }
329 }
330
331 impl<Q, A> Ruleset<Q, A> for BTreeMap<Head<Q, A>, Tail<Q, A>>
332 where
333 Q: RawState + Ord,
334 A: Ord,
335 {
336 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
337 self.get(head)
338 }
339
340 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
341 self.iter().find_map(|(h, t)| {
342 if h.state().view() == state && h.symbol() == sym {
343 Some(t)
344 } else {
345 None
346 }
347 })
348 }
349 }
350}
351
352#[cfg(feature = "hashbrown")]
353mod impl_hashbrown {
354 use super::*;
355 use core::hash::Hash;
356 use hashbrown::{HashMap, HashSet};
357
358 impl<I, Q, A> RawRuleset<Q, A> for HashSet<I>
359 where
360 I: Instruction<Q, A>,
361 Q: RawState + Eq + Hash,
362 A: Eq + Hash,
363 {
364 type Rule = Rule<Q, A>;
365
366 seal! {}
367
368 fn len(&self) -> usize {
369 <HashSet<I>>::len(self)
370 }
371
372 fn is_empty(&self) -> bool {
373 <HashSet<I>>::is_empty(self)
374 }
375 }
376
377 impl<Q, A> Ruleset<Q, A> for HashSet<Rule<Q, A>>
378 where
379 Q: RawState + Eq + Hash,
380 A: Eq + Hash,
381 {
382 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
383 get_tail!(self.iter(), head)
384 }
385
386 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
387 find_tail!(self.iter(), (state, sym))
388 }
389 }
390
391 impl<Q, A> RawRuleset<Q, A> for HashMap<Head<Q, A>, Tail<Q, A>>
392 where
393 Q: RawState + Eq + Hash,
394 A: Eq + Hash,
395 {
396 type Rule = Rule<Q, A>;
397
398 seal! {}
399
400 fn len(&self) -> usize {
401 <HashMap<Head<Q, A>, Tail<Q, A>>>::len(self)
402 }
403
404 fn is_empty(&self) -> bool {
405 <HashMap<Head<Q, A>, Tail<Q, A>>>::is_empty(self)
406 }
407 }
408
409 impl<Q, A> Ruleset<Q, A> for HashMap<Head<Q, A>, Tail<Q, A>>
410 where
411 Q: RawState + Eq + Hash,
412 A: Eq + Hash,
413 {
414 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
415 self.get(head)
416 }
417
418 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
419 self.iter().find_map(|(h, t)| {
420 if h.state().view() == state && h.symbol() == sym {
421 Some(t)
422 } else {
423 None
424 }
425 })
426 }
427 }
428}
429
430#[cfg(feature = "std")]
431mod impl_std {
432 use super::*;
433 use core::hash::Hash;
434 use std::collections::{HashMap, HashSet};
435
436 impl<I, Q, A> RawRuleset<Q, A> for HashSet<I>
437 where
438 I: Instruction<Q, A>,
439 Q: RawState + Eq + Hash,
440 A: Eq + Hash,
441 {
442 type Rule = Rule<Q, A>;
443
444 seal! {}
445
446 fn len(&self) -> usize {
447 <HashSet<I>>::len(self)
448 }
449
450 fn is_empty(&self) -> bool {
451 <HashSet<I>>::is_empty(self)
452 }
453 }
454
455 impl<Q, A> Ruleset<Q, A> for HashSet<Rule<Q, A>>
456 where
457 Q: RawState + Eq + Hash,
458 A: Eq + Hash,
459 {
460 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
461 get_tail!(self.iter(), head)
462 }
463
464 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
465 find_tail!(self.iter(), (state, sym))
466 }
467 }
468
469 impl<Q, A> RawRuleset<Q, A> for HashMap<Head<Q, A>, Tail<Q, A>>
470 where
471 Q: RawState + Eq + Hash,
472 A: Eq + Hash,
473 {
474 type Rule = Rule<Q, A>;
475
476 seal! {}
477
478 fn len(&self) -> usize {
479 <HashMap<Head<Q, A>, Tail<Q, A>>>::len(self)
480 }
481
482 fn is_empty(&self) -> bool {
483 <HashMap<Head<Q, A>, Tail<Q, A>>>::is_empty(self)
484 }
485 }
486
487 impl<Q, A> Ruleset<Q, A> for HashMap<Head<Q, A>, Tail<Q, A>>
488 where
489 Q: RawState + Eq + Hash,
490 A: Eq + Hash,
491 {
492 fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>> {
493 self.get(head)
494 }
495
496 fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>> {
497 self.iter().find_map(|(h, t)| {
498 if h.state() == *state && h.symbol() == sym {
499 Some(t)
500 } else {
501 None
502 }
503 })
504 }
505 }
506}