more_itertools/augmenting/
padded.rs

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