layered_nlp/ll_line/x/
any_of.rs

1use 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}