layered_nlp/ll_line/x/
all.rs

1use 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        // ╰─╯A(1)
35        // ╰─╯A(2)
36        // ╰──╯A(3)
37        // ╰─╯B(1)
38        // ╰─╯B(2)
39        // ╰──╯B(3)
40        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        // .0 = (&'m A(1), EndIdx(3)); (&'m A(2), EndIdx(3)); (&'m A(3), EndIdx(4))
55        // .1 = (&'m B(1), EndIdx(3)); (&'m B(2), EndIdx(3)); (&'m B(3), EndIdx(4))
56
57        // Out[0] = (&'m A(1), &'m B(1)), EndIdx(3)
58        // Out[1] = (&'m A(2), &'m B(1)), EndIdx(3)
59        // Out[2] = (&'m A(1), &'m B(2)), EndIdx(3)
60        // Out[3] = (&'m A(2), &'m B(2)), EndIdx(3)
61
62        // Out[4] = (&'m A(3), &'m B(3)), EndIdx(4)
63
64        // match up the EndIdx values...
65    }
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        // match up the EndIdx values...
78        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}