makepad_code_editor/
iter.rs

1pub trait IteratorExt: Iterator {
2    fn merge<F>(self, f: F) -> Merge<Self, F>
3    where
4        Self: Sized,
5        F: FnMut(Self::Item, Self::Item) -> Result<Self::Item, (Self::Item, Self::Item)>;
6}
7
8impl<T> IteratorExt for T
9where
10    T: Iterator,
11{
12    fn merge<F>(self, f: F) -> Merge<Self, F>
13    where
14        Self: Sized,
15        F: FnMut(Self::Item, Self::Item) -> Result<Self::Item, (Self::Item, Self::Item)>,
16    {
17        Merge {
18            prev_item: None,
19            iter: self,
20            f,
21        }
22    }
23}
24
25#[derive(Clone, Debug)]
26pub struct Merge<I, F>
27where
28    I: Iterator,
29{
30    prev_item: Option<I::Item>,
31    iter: I,
32    f: F,
33}
34
35impl<I, F> Iterator for Merge<I, F>
36where
37    I: Iterator,
38    F: FnMut(I::Item, I::Item) -> Result<I::Item, (I::Item, I::Item)>,
39{
40    type Item = I::Item;
41
42    fn next(&mut self) -> Option<Self::Item> {
43        loop {
44            match (self.prev_item.take(), self.iter.next()) {
45                (Some(prev_item), Some(item)) => match (self.f)(prev_item, item) {
46                    Ok(merged_item) => {
47                        self.prev_item = Some(merged_item);
48                        continue;
49                    }
50                    Err((prev_item, item)) => {
51                        self.prev_item = Some(item);
52                        break Some(prev_item);
53                    }
54                },
55                (None, Some(item)) => {
56                    self.prev_item = Some(item);
57                    continue;
58                }
59                (Some(prev_item), None) => break Some(prev_item),
60                (None, None) => break None,
61            }
62        }
63    }
64}