more_itertools/others/
cache_until.rs

1use std::collections::VecDeque;
2use crate::{error, error::Error, utils::vecdeque_2_vec};
3
4struct CacheUntil<T> {
5    buf: VecDeque<T>,
6    iter: Box<dyn Iterator<Item = Result<T,Error>>>,
7    pred: fn(&T) -> Result<bool, Error>,
8    pred_execute_count: i128,
9    max_pred_execute_count: i128,
10    pred_append_tail: bool,
11    iter_finished: bool
12}
13
14impl<T> Iterator for CacheUntil<T> 
15where T: Clone
16{
17    type Item = Result<Vec<T>, Error>;
18
19    fn next(&mut self) -> Option<Self::Item> {
20        if self.iter_finished {
21            return None;
22        }
23
24        loop {
25            if let Some(_next) = self.iter.next() {
26                match _next {
27                    Ok(ok_next) => {
28                        let pred_ret = (self.pred)(&ok_next);
29                        
30                        match pred_ret {
31                            Ok(ok_pred_ret) => {
32                                if ok_pred_ret && (self.max_pred_execute_count < 0 || self.pred_execute_count < self.max_pred_execute_count) {
33                                    self.pred_execute_count += 1;
34                                    self.buf.push_back(ok_next);
35                                    let ret;
36                                    if self.pred_append_tail {
37                                        ret = vecdeque_2_vec(&mut self.buf);
38                                    } else {
39                                        let pop_tail = self.buf.pop_back();
40                                        ret = vecdeque_2_vec(&mut self.buf);
41                                        self.buf.push_back(pop_tail.unwrap());
42                                    }
43                                    return Some(Ok(ret));
44                                } else {
45                                    self.buf.push_back(ok_next);
46                                }
47                            },
48                            Err(err_pred_ret) => {
49                                self.iter_finished = true;
50                                return Some(Err(error::any_error(err_pred_ret.kind(), "[cache_util] ".to_string()+err_pred_ret.message().unwrap())));
51                            }
52                        }
53                    },
54                    Err(err_next) => { // upstream error
55                        self.iter_finished = true;
56                        return Some(Err(err_next));
57                    }
58                }
59            } else {
60                let ret = vecdeque_2_vec(&mut self.buf);
61                self.iter_finished = true;
62                return Some(Ok(ret));
63            }
64        }
65
66    }
67}
68
69pub fn cache_until<T>(iter: Box<dyn Iterator<Item = Result<T,Error>>>, 
70    pred: fn(&T) -> Result<bool, Error>,
71    max_pred_execute_count: i128,
72    pred_append_tail: bool) -> Box<dyn Iterator<Item = Result<Vec<T>,Error>>> 
73where T: Clone + 'static
74{
75    return Box::new(CacheUntil {
76        buf: VecDeque::new(),
77        iter,
78        pred,
79        pred_execute_count: 0,
80        max_pred_execute_count,
81        pred_append_tail,
82        iter_finished: false
83    });
84}
85
86
87#[cfg(test)]
88mod tests {
89
90    use crate::utils::{generate_okok_iterator, generate_okokerr_iterator};
91
92    use super::*;
93
94    #[test]
95    fn test1() {
96        let v = vec![1,2,3,4,5];
97        let mut it = cache_until(generate_okok_iterator(v), |x| {Ok(*x==1||*x==2||*x==5)}, -1, true);
98        assert_eq!(Some(Ok(vec![1])), it.next());
99        assert_eq!(Some(Ok(vec![2])), it.next());
100        assert_eq!(Some(Ok(vec![3, 4, 5])), it.next());
101        assert_eq!(Some(Ok(Vec::<i32>::new())), it.next());
102        assert_eq!(None, it.next());
103    }
104
105    #[test]
106    fn test1_max_pred_execute_count() {
107        let v = vec![1,2,3,4,5];
108        let mut it = cache_until(generate_okok_iterator(v), |x| {Ok(*x==1||*x==2||*x==5)}, 2, true);
109        assert_eq!(Some(Ok(vec![1])), it.next());
110        assert_eq!(Some(Ok(vec![2])), it.next());
111        assert_eq!(Some(Ok(vec![3, 4, 5])), it.next());
112        // assert_eq!(Some(Ok(Vec::<i32>::new())), it.next());
113        assert_eq!(None, it.next());
114    }
115
116    #[test]
117    fn test1_error() {
118        let v = vec![1,2,3,4,5];
119        let mut it = cache_until(generate_okokerr_iterator(v, error::overflow_error("[test]".to_string())), 
120                |x| {Ok(*x==1||*x==2||*x==5)}, 2, true);
121        assert_eq!(Some(Ok(vec![1])), it.next());
122        assert_eq!(Some(Ok(vec![2])), it.next());
123        assert_eq!(error::Kind::OverflowError, it.next().unwrap().err().unwrap().kind());
124        assert_eq!(None, it.next());
125    }
126
127    #[test]
128    fn test2() {
129        let v = vec![1,2,3,4,5];
130        let mut it = cache_until(generate_okok_iterator(v), |x| {Ok(*x==1||*x==2||*x==5)}, -1, false);
131        assert_eq!(Some(Ok(Vec::<i32>::new())), it.next());
132        assert_eq!(Some(Ok(vec![1])), it.next());
133        assert_eq!(Some(Ok(vec![2,3,4])), it.next());
134        assert_eq!(Some(Ok(vec![5])), it.next());
135        assert_eq!(None, it.next());
136    }
137
138    #[test]
139    fn test2_max_pred_execute_count() {
140        let v = vec![1,2,3,4,5];
141        let mut it = cache_until(generate_okok_iterator(v), |x| {Ok(*x==1||*x==2||*x==5)}, 2, false);
142        assert_eq!(Some(Ok(Vec::<i32>::new())), it.next());
143        assert_eq!(Some(Ok(vec![1])), it.next());
144        assert_eq!(Some(Ok(vec![2,3,4,5])), it.next());
145        assert_eq!(None, it.next());
146    }
147
148    #[test]
149    fn test2_error() {
150        let v = vec![1,2,3,4,5];
151        let mut it = cache_until(generate_okokerr_iterator(v, error::overflow_error("[test]".to_string())), 
152                |x| {Ok(*x==1||*x==2||*x==5)}, 2, false);
153        assert_eq!(Some(Ok(Vec::<i32>::new())), it.next());
154        assert_eq!(Some(Ok(vec![1])), it.next());
155        assert_eq!(error::Kind::OverflowError, it.next().unwrap().err().unwrap().kind());
156        assert_eq!(None, it.next());
157    }
158}