more-itertools 0.1.6

A rust implementation of python more-itertools
Documentation
use std::rc::Rc;

use crate::sequence::Sequence;


pub struct PartitionInner<T> {
    buf: Box<dyn Sequence<T>>,
    pred: fn(&T) -> bool
}

pub struct Partition<T> {
    inner: Rc<PartitionInner<T>>
}

pub struct CursorFalse<T> {
    inner: Rc<PartitionInner<T>>,
    _next: usize
}

pub struct CursorTrue<T> {
    inner: Rc<PartitionInner<T>>,
    _next: usize
}

impl<T> Iterator for CursorFalse<T>
where
T: Clone
{
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            if self._next >= self.inner.buf.len() {
                return None;
            }
            let t = self.inner.buf.get(self._next).unwrap();
            self._next += 1;
            if !(self.inner.pred)(t) {
                return Some(t.clone());
            }
        }
    }
}

impl<T> Iterator for CursorTrue<T>
where
T: Clone
{
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            if self._next >= self.inner.buf.len() {
                return None;
            }
            let t = self.inner.buf.get(self._next).unwrap();
            self._next += 1;
            if (self.inner.pred)(t) {
                return Some(t.clone());
            }
        }
    }
}

impl<T> Partition<T> 
where T: Clone + 'static
{
    pub fn new(buf: Box<dyn Sequence<T>>, pred: fn(&T) -> bool) -> Partition<T> {
        let inner = PartitionInner {
            buf: buf,
            pred: pred
        };

        let ret = Partition {
            inner: Rc::new(inner)
        };

        return ret;
    }

    pub fn get_cursor(&self) -> (Box<dyn Iterator<Item = T>>, Box<dyn Iterator<Item = T>>){
        let cur_false: Box<dyn Iterator<Item = T>> = Box::new(CursorFalse {
            inner: Rc::clone(&self.inner),
            _next: 0
        });
        let cur_true: Box<dyn Iterator<Item = T>> = Box::new(CursorTrue {
            inner: Rc::clone(&self.inner),
            _next: 0
        });
        return (cur_false, cur_true);
    }
}

pub fn partition<T>(buf: Box<dyn Sequence<T>>, pred: fn(&T) -> bool) -> (Box<dyn Iterator<Item = T>>, Box<dyn Iterator<Item = T>>) 
where T: Clone + 'static
{
    let p = Partition::new(buf, pred);
    return p.get_cursor();
}


#[cfg(test)]
mod tests {
    use crate::sequence::create_seq_from_vec;

    use super::*;

    #[test]
    fn test1() {
        let v = vec![1,2,3,4,5,6,7,8,9,10];

        let (cur_false, cur_true) = partition(create_seq_from_vec(v), |x| {x % 2 == 1});
        assert_eq!(vec![2, 4, 6, 8, 10], cur_false.collect::<Vec<_>>());
        assert_eq!(vec![1, 3, 5, 7, 9], cur_true.collect::<Vec<_>>());
    }
}