layered_nlp/ll_line/x/
all.rs1use super::{LLLine, ToIdx, XDirection, XMatch};
2
3pub trait All {
4 type Out;
5
6 fn into_all(self) -> Self::Out;
7}
8
9impl<A, B> All for (A, B) {
10 type Out = All2<A, B>;
11
12 fn into_all(self) -> Self::Out {
13 All2(self.0, self.1)
14 }
15}
16
17impl<A, B, C> All for (A, B, C) {
18 type Out = All3<A, B, C>;
19
20 fn into_all(self) -> Self::Out {
21 All3(self.0, self.1, self.2)
22 }
23}
24
25pub struct All2<A, B>(pub A, pub B);
26
27impl<'l, A: XMatch<'l>, B: XMatch<'l>> XMatch<'l> for All2<A, B> {
28 type Out = (A::Out, B::Out);
29
30 fn go<M>(&self, direction: &M, ll_line: &'l LLLine) -> Vec<(Self::Out, ToIdx)>
31 where
32 M: XDirection<'l>,
33 {
34 let bs = self.1.go(direction, ll_line);
41 self.0
42 .go(direction, ll_line)
43 .into_iter()
44 .flat_map(|(a, a_to_idx)| {
45 bs.iter().filter_map(move |(b, b_to_idx)| {
46 if a_to_idx == *b_to_idx {
47 Some(((a, *b), a_to_idx))
48 } else {
49 None
50 }
51 })
52 })
53 .collect()
54 }
66}
67
68pub struct All3<A, B, C>(pub A, pub B, pub C);
69
70impl<'l, A: XMatch<'l>, B: XMatch<'l>, C: XMatch<'l>> XMatch<'l> for All3<A, B, C> {
71 type Out = (A::Out, B::Out, C::Out);
72
73 fn go<M>(&self, direction: &M, ll_line: &'l LLLine) -> Vec<(Self::Out, ToIdx)>
74 where
75 M: XDirection<'l>,
76 {
77 let bs = self.1.go(direction, ll_line);
79 let cs = self.2.go(direction, ll_line);
80 self.0
81 .go(direction, ll_line)
82 .into_iter()
83 .flat_map(|(a, a_to_idx)| {
84 let cs_iter = cs.iter();
85 bs.iter().flat_map(move |(b, b_to_idx)| {
86 cs_iter.clone().filter_map(move |(c, c_to_idx)| {
87 if &a_to_idx == b_to_idx && &a_to_idx == c_to_idx {
88 Some(((a, *b, *c), a_to_idx))
89 } else {
90 None
91 }
92 })
93 })
94 })
95 .collect()
96 }
97}