pusherator/
flatten.rs

1use std::marker::PhantomData;
2
3use super::{Pusherator, PusheratorBuild};
4
5pub struct Flatten<Next, In> {
6    next: Next,
7    _marker: PhantomData<fn(In)>,
8}
9impl<Next, In> Pusherator for Flatten<Next, In>
10where
11    Next: Pusherator<Item = In::Item>,
12    In: IntoIterator,
13{
14    type Item = In;
15    fn give(&mut self, item: Self::Item) {
16        for x in item {
17            self.next.give(x);
18        }
19    }
20}
21impl<Next, In> Flatten<Next, In>
22where
23    Next: Pusherator<Item = In::Item>,
24    In: IntoIterator,
25{
26    pub fn new(next: Next) -> Self {
27        Self {
28            next,
29            _marker: PhantomData,
30        }
31    }
32}
33
34pub struct FlattenBuild<Prev>
35where
36    Prev: PusheratorBuild,
37    Prev::ItemOut: IntoIterator,
38{
39    prev: Prev,
40}
41impl<Prev> FlattenBuild<Prev>
42where
43    Prev: PusheratorBuild,
44    Prev::ItemOut: IntoIterator,
45{
46    pub fn new(prev: Prev) -> Self {
47        Self { prev }
48    }
49}
50impl<Prev> PusheratorBuild for FlattenBuild<Prev>
51where
52    Prev: PusheratorBuild,
53    Prev::ItemOut: IntoIterator,
54{
55    type ItemOut = <Prev::ItemOut as IntoIterator>::Item;
56
57    type Output<Next: Pusherator<Item = Self::ItemOut>> =
58        Prev::Output<Flatten<Next, Prev::ItemOut>>;
59    fn push_to<Next>(self, input: Next) -> Self::Output<Next>
60    where
61        Next: Pusherator<Item = Self::ItemOut>,
62    {
63        self.prev.push_to(Flatten::new(input))
64    }
65}