fluffl 0.0.5

A cross-platform multimedia layer that exposes opengl,sockets,and audio utilities for desktop and browser
Documentation
pub struct GroupIterator<Iter, Key, KeyCB, ItemCB>
where
    Iter: Iterator,
    Key: PartialEq,
    ItemCB: Fn(&Iter::Item) + 'static,
    KeyCB: Fn(&Iter::Item) -> Key + 'static,
{
    prev_val: Option<Iter::Item>,
    prev_key: Option<Key>,
    item_stream: Iter,
    per_item: ItemCB,
    first_key: Option<Key>,
    get_key: KeyCB,
}
impl<Iter, Key, KeyCB, ItemCB> GroupIterator<Iter, Key, KeyCB, ItemCB>
where
    Iter: Iterator,
    Key: PartialEq,
    ItemCB: Fn(&Iter::Item),
    KeyCB: Fn(&Iter::Item) -> Key,
{
    pub fn new(iterator: Iter, key_cb: KeyCB, item_cb: ItemCB) -> Self {
        Self {
            prev_key: None,
            prev_val: None,
            item_stream: iterator,
            get_key: key_cb,
            per_item: item_cb,
            first_key: None,
        }
    }
}

impl<Iter, Key, KeyCB, ItemCB> Iterator for GroupIterator<Iter, Key, KeyCB, ItemCB>
where
    Iter: Iterator,
    Key: PartialEq + Copy,
    ItemCB: Fn(&Iter::Item) + Copy + 'static,
    KeyCB: Fn(&Iter::Item) -> Key + Copy + 'static,
    Iter::Item: Copy,
{
    type Item = Option<Iter::Item>;

    fn next(&mut self) -> Option<Self::Item> {
        let item = self.item_stream.next();
        let get_key = self.get_key;
        let per_item = self.per_item;

        match (item, self.prev_key.as_ref()) {
            (Some(i), None) => {
                let key = get_key(&i);
                self.first_key = Some(key);
                self.prev_val = Some(i);
                self.prev_key = Some(key);
                per_item(&i);
                Some(None)
            }
            (Some(i), Some(prev_key)) => {
                let prev_val = self.prev_val;
                let current_key = get_key(&i);
                let key = get_key(&i);

                let group = if !current_key.eq(prev_key) {
                    Some(prev_val)
                } else {
                    Some(None)
                };

                self.prev_val = Some(i);
                self.prev_key = Some(key);
                per_item(&i);

                group
            }
            _ => self.prev_val.take().map(Option::Some),
        }
    }
}

#[test]
fn sanity() {
    let list: Vec<u32> = vec![0, 0, 0];

    GroupIterator::new(
        list.iter().enumerate(),
        |&a| a.1,
        |b| println!("item:{:?}", b),
    )
    .flatten()
    .for_each(|b| println!("group is {}", b.1));
}