makepad-code-editor 1.0.0

Makepad studio
Documentation
pub trait IteratorExt: Iterator {
    fn merge<F>(self, f: F) -> Merge<Self, F>
    where
        Self: Sized,
        F: FnMut(Self::Item, Self::Item) -> Result<Self::Item, (Self::Item, Self::Item)>;
}

impl<T> IteratorExt for T
where
    T: Iterator,
{
    fn merge<F>(self, f: F) -> Merge<Self, F>
    where
        Self: Sized,
        F: FnMut(Self::Item, Self::Item) -> Result<Self::Item, (Self::Item, Self::Item)>,
    {
        Merge {
            prev_item: None,
            iter: self,
            f,
        }
    }
}

#[derive(Clone, Debug)]
pub struct Merge<I, F>
where
    I: Iterator,
{
    prev_item: Option<I::Item>,
    iter: I,
    f: F,
}

impl<I, F> Iterator for Merge<I, F>
where
    I: Iterator,
    F: FnMut(I::Item, I::Item) -> Result<I::Item, (I::Item, I::Item)>,
{
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            match (self.prev_item.take(), self.iter.next()) {
                (Some(prev_item), Some(item)) => match (self.f)(prev_item, item) {
                    Ok(merged_item) => {
                        self.prev_item = Some(merged_item);
                        continue;
                    }
                    Err((prev_item, item)) => {
                        self.prev_item = Some(item);
                        break Some(prev_item);
                    }
                },
                (None, Some(item)) => {
                    self.prev_item = Some(item);
                    continue;
                }
                (Some(prev_item), None) => break Some(prev_item),
                (None, None) => break None,
            }
        }
    }
}