list_fn/
flat_map.rs

1use super::*;
2
3pub trait FlatMapFn {
4    type Input;
5    type OutputList: ListFn;
6    /// Map the given `input` item into a list.
7    fn map(&self, input: Self::Input) -> Self::OutputList;
8}
9
10pub struct FlatMapList<I: ListFn, F: FlatMapFn<Input = I::Item>> {
11    flat_map: F,
12    input_list: I,
13    output_list: Option<F::OutputList>,
14}
15
16impl<I: ListFn, F: FlatMapFn<Input = I::Item>> ListFn for FlatMapList<I, F> {
17    type Item = <F::OutputList as ListFn>::Item;
18    type End = I::End;
19    fn next(mut self) -> ListState<Self> {
20        loop {
21            match self.output_list {
22                Some(item_list) => match item_list.next() {
23                    ListState::Some(some) => {
24                        return ListState::some(
25                            some.first,
26                            FlatMapList {
27                                flat_map: self.flat_map,
28                                input_list: self.input_list,
29                                output_list: Some(some.next),
30                            },
31                        )
32                    }
33                    ListState::End(..) => self.output_list = None,
34                },
35                None => match self.input_list.next() {
36                    ListState::Some(some) => {
37                        self.input_list = some.next;
38                        self.output_list = Some(self.flat_map.map(some.first));
39                    }
40                    ListState::End(end) => return ListState::End(end),
41                },
42            }
43        }
44    }
45}
46
47pub trait FlatMap: ListFn {
48    fn flat_map<F: FlatMapFn<Input = Self::Item>>(self, flat_map: F) -> FlatMapList<Self, F> {
49        FlatMapList {
50            input_list: self,
51            flat_map,
52            output_list: None,
53        }
54    }
55}
56
57impl<S: ListFn> FlatMap for S {}