layered_nlp/ll_line/x/
any_of.rs1use super::{LLLine, ToIdx, XDirection, XMatch};
2
3pub trait AnyOf {
4 type Out;
5
6 fn into_any(self) -> Self::Out;
7}
8
9impl<A, B> AnyOf for (A, B) {
10 type Out = AnyOf2Matcher<A, B>;
11
12 fn into_any(self) -> Self::Out {
13 AnyOf2Matcher(self.0, self.1)
14 }
15}
16
17impl<A, B, C> AnyOf for (A, B, C) {
18 type Out = AnyOf3Matcher<A, B, C>;
19
20 fn into_any(self) -> Self::Out {
21 AnyOf3Matcher(self.0, self.1, self.2)
22 }
23}
24
25pub struct AnyOf2Matcher<A, B>(pub A, pub B);
26
27#[derive(Clone, Copy, Debug, PartialEq, Eq)]
28pub enum AnyOf2<A, B> {
29 A(A),
30 B(B),
31}
32
33impl<'l, A: XMatch<'l>, B: XMatch<'l>> XMatch<'l> for AnyOf2Matcher<A, B> {
34 type Out = AnyOf2<A::Out, B::Out>;
35
36 fn go<M>(&self, direction: &M, ll_line: &'l LLLine) -> Vec<(Self::Out, ToIdx)>
37 where
38 M: XDirection<'l>,
39 {
40 let a = self.0.go(direction, ll_line);
41
42 if !a.is_empty() {
43 a.into_iter().map(|(a, idx)| (AnyOf2::A(a), idx)).collect()
44 } else {
45 self.1
46 .go(direction, ll_line)
47 .into_iter()
48 .map(|(b, idx)| (AnyOf2::B(b), idx))
49 .collect()
50 }
51 }
52}
53
54pub struct AnyOf3Matcher<A, B, C>(pub A, pub B, pub C);
55
56#[derive(Clone, Copy, Debug, PartialEq, Eq)]
57pub enum AnyOf3<A, B, C> {
58 A(A),
59 B(B),
60 C(C),
61}
62
63impl<'l, A: XMatch<'l>, B: XMatch<'l>, C: XMatch<'l>> XMatch<'l> for AnyOf3Matcher<A, B, C> {
64 type Out = AnyOf3<A::Out, B::Out, C::Out>;
65
66 fn go<M>(&self, direction: &M, ll_line: &'l LLLine) -> Vec<(Self::Out, ToIdx)>
67 where
68 M: XDirection<'l>,
69 {
70 let a = self.0.go(direction, ll_line);
71
72 if !a.is_empty() {
73 a.into_iter().map(|(a, idx)| (AnyOf3::A(a), idx)).collect()
74 } else {
75 let b = self.1.go(direction, ll_line);
76
77 if !b.is_empty() {
78 b.into_iter().map(|(b, idx)| (AnyOf3::B(b), idx)).collect()
79 } else {
80 self.2
81 .go(direction, ll_line)
82 .into_iter()
83 .map(|(c, idx)| (AnyOf3::C(c), idx))
84 .collect()
85 }
86 }
87 }
88}