more_itertools/augmenting/
repeat_last.rs

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