more-itertools 0.1.6

A rust implementation of python more-itertools
Documentation
use std::{cell::RefCell, collections::VecDeque, rc::Rc};
use crate::error::Error;

#[allow(dead_code)]
struct TeeInner<T> 
where
T: Clone
{
    buf1: VecDeque<T>,
    buf2: VecDeque<T>,
    iter: Box<dyn Iterator<Item = Result<T, Error>>>,
    iter_finished: bool,
    iter_error: Option<Error>
}

impl<T> TeeInner<T> 
where
T: Clone
{
    pub fn new(iter: Box<dyn Iterator<Item = Result<T, Error>>>) -> TeeInner<T> {
        return TeeInner {
            buf1: VecDeque::new(),
            buf2: VecDeque::new(),
            iter,
            iter_finished: false,
            iter_error: None
        };
    }
}

pub struct Tee<T> 
where
T: Clone 
{
    inner: Rc<RefCell<TeeInner<T>>>
}

struct TeeCursor<T> 
where
T: Clone
{
    no: usize,
    inner: Rc<RefCell<TeeInner<T>>>
}

impl<T> Iterator for TeeCursor<T> 
where
T: Clone
{
    type Item = Result<T, Error>;

    fn next(&mut self) -> Option<Self::Item> {
        let _next = self.inner.borrow_mut().iter.next();
        match _next {
            None => {
                self.inner.borrow_mut().iter_finished = true;
            }, 
            Some(v) => {
                if v.is_ok() {
                    self.inner.borrow_mut().buf1.push_back(v.as_ref().ok().unwrap().clone());
                    self.inner.borrow_mut().buf2.push_back(v.as_ref().ok().unwrap().clone());
                } else {
                    self.inner.borrow_mut().iter_error = Some(v.err().unwrap());
                }
            }
        }
        if self.no == 1 {
            if self.inner.borrow_mut().iter_finished && self.inner.borrow_mut().buf1.len() == 0 {
                return None;
            } else {
                return Some(Ok(self.inner.borrow_mut().buf1.pop_front().unwrap()));
            }
        } else if self.no == 2 {
            if self.inner.borrow_mut().iter_finished && self.inner.borrow_mut().buf2.len() == 0 {
                return None;
            } else {
                return Some(Ok(self.inner.borrow_mut().buf2.pop_front().unwrap()));
            }
        } else {
            return None;
        }
    }
}

impl<T> Tee<T> 
where
T: Clone + 'static
{
    pub fn new(iter: Box<dyn Iterator<Item=Result<T,Error>>>) -> Tee<T> {
        let inner = TeeInner::new(iter);

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

        return ret;
    }

    pub fn iter(&self) -> (Box<dyn Iterator<Item=Result<T,Error>>>, Box<dyn Iterator<Item=Result<T,Error>>>) {
        let ret0: Box<dyn Iterator<Item=Result<T,Error>>> = Box::new(TeeCursor {
            no: 1,
            inner: Rc::clone(&self.inner)
        });

        let ret1: Box<dyn Iterator<Item=Result<T,Error>>> = Box::new(TeeCursor {
            no: 2,
            inner: Rc::clone(&self.inner)
        });

        return (ret0, ret1);
    }
}



pub fn tee<T>(iterator: Box<dyn Iterator<Item=Result<T,Error>>>) -> (Box<dyn Iterator<Item=Result<T,Error>>>, Box<dyn Iterator<Item=Result<T,Error>>>) 
where
T: Clone + 'static
{
    let t = Tee::new(iterator);
    return t.iter();
}

#[cfg(test)]
mod tests {
    use std::vec;

    use crate::utils::extract_value_from_result_vec;
    use crate::utils::generate_okok_iterator;

    use super::*;

    #[test]
    fn test1() {
        let v = generate_okok_iterator(vec![1,2,3,4,5]);
        let (t1,t2) = tee(v);
        let ret1 = extract_value_from_result_vec(t1.collect::<Vec<_>>());
        assert_eq!(vec![1, 2, 3, 4, 5], ret1.0);
        assert_eq!(vec![1, 2, 3, 4, 5], extract_value_from_result_vec(t2.collect::<Vec<_>>()).0);

        let v = generate_okok_iterator(vec![1,2,3,4,5]);
        let (mut t1, mut t2) = tee(v);
        assert_eq!(Some(1), t1.next().unwrap().ok());
        assert_eq!(Some(1), t2.next().unwrap().ok());
        assert_eq!(Some(2), t1.next().unwrap().ok());
        assert_eq!(Some(2), t2.next().unwrap().ok());
        assert_eq!(Some(3), t1.next().unwrap().ok());
        assert_eq!(Some(3), t2.next().unwrap().ok());
        assert_eq!(Some(4), t1.next().unwrap().ok());
        assert_eq!(Some(4), t2.next().unwrap().ok());
        assert_eq!(Some(5), t1.next().unwrap().ok());
        assert_eq!(Some(5), t2.next().unwrap().ok());
        assert_eq!(None, t1.next());
        assert_eq!(None, t2.next());

        let v = generate_okok_iterator(vec![1,2,3,4,5]);
        let (mut t1, mut t2) = tee(v);
        assert_eq!(Some(1), t1.next().unwrap().ok());
        assert_eq!(Some(2), t1.next().unwrap().ok());
        assert_eq!(Some(1), t2.next().unwrap().ok());
        assert_eq!(Some(2), t2.next().unwrap().ok());

        assert_eq!(Some(3), t1.next().unwrap().ok());
        assert_eq!(Some(4), t1.next().unwrap().ok());
        assert_eq!(Some(3), t2.next().unwrap().ok());
        assert_eq!(Some(4), t2.next().unwrap().ok());

        assert_eq!(Some(5), t1.next().unwrap().ok());
        assert_eq!(Some(5), t2.next().unwrap().ok());

        assert_eq!(None, t1.next());
        assert_eq!(None, t2.next());

        let v = generate_okok_iterator(vec![1,2,3,4]);
        let (mut t1, mut t2) = tee(v);
        assert_eq!(Some(1), t1.next().unwrap().ok());
        assert_eq!(Some(2), t1.next().unwrap().ok());
        assert_eq!(Some(3), t1.next().unwrap().ok());
        assert_eq!(Some(1), t2.next().unwrap().ok());
        assert_eq!(Some(2), t2.next().unwrap().ok());
        assert_eq!(Some(3), t2.next().unwrap().ok());

        assert_eq!(Some(4), t1.next().unwrap().ok());
        assert_eq!(Some(4), t2.next().unwrap().ok());

        assert_eq!(None, t1.next());
        assert_eq!(None, t2.next());
    }
}