more_itertools/others/
repeat_append_default.rs

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