roxy_cli 0.1.2

A command-line static site generator
pub(crate) trait Head: Iterator {
    fn head(self) -> Option<(Self::Item, Self)>
    where
        Self: Sized;
}

impl<I: Iterator> Head for I {
    fn head(mut self) -> Option<(Self::Item, Self)> {
        match self.next() {
            Some(x) => Some((x, self)),
            None => None,
        }
    }
}

#[derive(Debug)]
pub(crate) struct MapFold<I, F, V> {
    iter: I,
    f: F,
    accum: V,
}

impl<I, F, V> MapFold<I, F, V> {
    pub fn new(iter: I, init: V, f: F) -> MapFold<I, F, V> {
        Self {
            iter,
            f,
            accum: init,
        }
    }
}

impl<I: Iterator, F: FnMut(&V, &I::Item) -> V, V: Clone> Iterator for MapFold<I, F, V> {
    type Item = V;

    fn next(&mut self) -> Option<Self::Item> {
        self.accum = (self.f)(&self.accum, &self.iter.next()?);
        Some(self.accum.clone())
    }
}

pub(crate) trait MapFoldExt {
    type Item;

    fn map_fold<B, F>(self, init: B, f: F) -> MapFold<Self, F, B>
    where
        Self: Sized,
        F: FnMut(&B, &Self::Item) -> B,
    {
        MapFold::new(self, init, f)
    }
}

impl<I: Iterator> MapFoldExt for I {
    type Item = I::Item;
}