more_itertools/others/
cache_last.rs

1use std::{cell::RefCell, rc::Rc};
2
3use crate::error::Error;
4
5struct CacheLastInner<T> {
6    iter: Box<dyn Iterator<Item = Result<T, Error>>>,
7    iter_finished: bool,
8    // iter_error: Option<Error>,
9    last_item: Option<Result<T, Error>>,
10    emmit_last_next_loop: bool
11}
12
13pub struct CacheLast<T> {
14    cl_inner: Rc<RefCell<CacheLastInner<T>>>
15}
16
17struct CacheLastIter<T> {
18    cl_inner: Rc<RefCell<CacheLastInner<T>>>
19}
20
21impl<T> Iterator for CacheLastIter<T> 
22where T: Clone
23{
24    type Item = Result<T,Error>;
25
26    fn next(&mut self) -> Option<Self::Item> {
27        let mut inner = self.cl_inner.borrow_mut();
28
29        if inner.iter_finished {
30            return None;
31        }
32
33        if inner.emmit_last_next_loop {
34            inner.emmit_last_next_loop = false;
35            if let Some(v) = &inner.last_item {
36                return Some(v.clone());
37            } else {
38                return None;
39            }
40        }
41
42        let _next = inner.iter.next();
43        if let Some(_next2) = _next {
44            inner.last_item = Some(_next2.clone());
45            if let Err(_) = _next2 {
46                inner.iter_finished = true;
47            }
48            return Some(_next2);
49        } else {
50            inner.iter_finished = true;
51            //inner.last_item = None;
52            return None;
53        }
54    }
55}
56
57impl<T> CacheLast<T> 
58where
59T: Clone + 'static
60{
61    pub fn new(iter: Box<dyn Iterator<Item=Result<T,Error>>>) -> CacheLast<T> {
62        let inner = CacheLastInner {
63            iter,
64            iter_finished: false,
65            // iter_error: None,
66            last_item: None,
67            emmit_last_next_loop: false
68        };
69
70        let ret = CacheLast {
71            cl_inner: Rc::new(RefCell::new(inner))
72        };
73
74        return ret;
75    }
76
77    pub fn iter(&mut self) -> Box<dyn Iterator<Item = Result<T,Error>>> {
78        let ret0: Box<dyn Iterator<Item=Result<T,Error>>> = Box::new(CacheLastIter {
79            cl_inner: Rc::clone(&self.cl_inner)
80        });
81        return ret0;
82    }
83
84    pub fn iter_with_emit_first(&mut self) -> Box<dyn Iterator<Item = Result<T,Error>>> {
85        let mut ret0: Box<dyn Iterator<Item=Result<T,Error>>> = Box::new(CacheLastIter {
86            cl_inner: Rc::clone(&self.cl_inner)
87        });
88
89        ret0.next();
90        self.insert_last_to_head();
91
92        return ret0;
93    }
94
95    pub fn insert_last_to_head(&mut self) {
96        let mut inner = self.cl_inner.borrow_mut();
97        // if inner.iter_finished {
98        //     return;
99        // }
100
101        if inner.last_item.is_none() {
102            return;
103        }
104
105        inner.emmit_last_next_loop = true;
106    }
107
108    pub fn is_empty(&self) -> bool {
109        let inner = self.cl_inner.borrow_mut();
110
111        return inner.last_item.is_none() && inner.iter_finished;
112    }
113
114    pub fn is_finished(&self) -> bool {
115        self.cl_inner.borrow_mut().iter_finished
116    }
117
118    pub fn get_last_item(&self) -> Option<Result<T, Error>> {
119        self.cl_inner.borrow_mut().last_item.clone()
120    }
121}
122
123pub fn cache_last<T>(iter: Box<dyn Iterator<Item = Result<T, Error>>>) -> CacheLast<T> 
124where T: Clone + 'static
125{
126    CacheLast::new(iter)
127}
128
129#[cfg(test)]
130mod tests {
131
132    use crate::utils::generate_okok_iterator;
133
134    use super::*;
135
136    #[test]
137    fn test1() {
138        let v = generate_okok_iterator(vec![1,2,3,4,5]);
139
140        let mut cl = cache_last(v);
141
142        let mut iter = cl.iter();
143
144        assert_eq!(1, iter.next().unwrap().ok().unwrap());
145        assert_eq!(2, iter.next().unwrap().ok().unwrap());
146        assert_eq!(3, iter.next().unwrap().ok().unwrap());
147
148        cl.insert_last_to_head();
149
150        assert_eq!(3, iter.next().unwrap().ok().unwrap());
151        assert_eq!(4, iter.next().unwrap().ok().unwrap());
152        assert_eq!(5, iter.next().unwrap().ok().unwrap());
153        assert_eq!(None, iter.next());
154    }
155
156    #[test]
157    fn test2() {
158        let v = generate_okok_iterator(Vec::<i32>::new());
159
160        let mut cl = cache_last(v);
161
162        let mut iter = cl.iter();
163
164        assert_eq!(None, iter.next());
165        assert_eq!(None, iter.next());
166    }
167}