more_itertools/augmenting/
repeat_each.rs

1use crate::error:: Error;
2
3pub struct RepeatEach<T> 
4where
5T: Clone
6{
7    // cl: CacheLast<T>,
8    iter: Box<dyn Iterator<Item = Result<T,Error>>>,
9    n: usize,
10    emit_count: usize,
11    iter_finished: bool,
12    last_item: Option<Result<T, Error>>
13}
14
15
16impl<T> Iterator for RepeatEach<T>
17where
18T: Clone
19{
20    type Item = Result<T, Error>;
21
22    fn next(&mut self) -> Option<Self::Item> {
23        loop {
24            if self.iter_finished {
25                return None;
26            }
27
28            if self.emit_count < self.n {
29                self.emit_count += 1;
30                return self.last_item.clone();
31            } else {
32                self.last_item = self.iter.next();
33                if self.last_item.is_none() {
34                    self.emit_count = 0;
35                    self.iter_finished = true;
36                    return None;
37                } else {
38                    match self.last_item.as_ref().unwrap() {
39                        Ok(_) => {
40                            self.emit_count = 0;
41                            continue;
42                        },
43                        Err(err_v) => {
44                            self.iter_finished = true;
45                            return Some(Err(err_v.clone()));
46                        }
47                    }
48                }
49            }
50        }
51    }
52}
53
54pub fn repeat_each<T>(mut iter: Box<dyn Iterator<Item=Result<T, Error>>>, n: usize) -> Box<dyn Iterator<Item=Result<T, Error>>>
55where
56T: Clone + 'static
57{
58    let last_item = iter.next();
59
60    Box::new(RepeatEach {
61        iter,
62        n,
63        emit_count: 0,
64        iter_finished: false,
65        last_item 
66    })
67}
68
69#[cfg(test)]
70mod tests {
71
72    use crate::{error, utils::{extract_value_from_result_vec, generate_okok_iterator, generate_okokerr_iterator}};
73
74    use super::*;
75
76    #[test]
77    fn test1() {
78        let v = vec![1,2,3];
79        let ret = repeat_each(generate_okok_iterator(v), 3).collect::<Vec<_>>();
80        assert_eq!(vec![1, 1, 1, 2, 2, 2, 3, 3, 3], extract_value_from_result_vec(ret).0);
81
82        let v = vec![1,2,3];
83        let ret = repeat_each(generate_okok_iterator(v), 0).collect::<Vec<_>>();
84        assert_eq!(0, ret.len());
85
86        let v = vec![1,2,3];
87        let ret = repeat_each(generate_okokerr_iterator(v, error::overflow_error("[test]".to_string())), 3).collect::<Vec<_>>();
88        let ret2 = extract_value_from_result_vec(ret);
89        assert_eq!(vec![1, 1, 1, 2, 2, 2, 3, 3, 3], ret2.0);
90        assert_eq!(error::Kind::OverflowError, ret2.1.unwrap().kind());
91    }
92}