more_itertools/others/
cache_last.rs1use 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 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 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 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.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}