more_itertools/itertools/
chain.rs

1use crate::error::Error;
2
3pub struct Chain<T> {
4    input: Vec<Box<dyn Iterator<Item=Result<T, Error>>>>,
5    cur_idx: usize,
6    iter_finished: bool,
7    iter_err: Option<Error>
8}
9
10impl<T> Iterator for Chain<T>
11{
12    type Item = Result<T, Error>;
13
14    fn next(&mut self) -> Option<Self::Item> {
15        loop {
16            if self.iter_finished {
17                return None;
18            }
19
20            if self.iter_err.is_some() {
21                return Some(Err(self.iter_err.as_ref().unwrap().clone()));
22            }
23    
24            if self.cur_idx >= self.input.len() {
25                self.iter_finished = true;
26                return None;
27            }
28    
29            let cur = self.input.get_mut(self.cur_idx).unwrap();
30            let _next = cur.next();
31            match _next {
32                None => {
33                    self.cur_idx += 1;
34                    continue;
35                },
36                Some(v) => {
37                    return Some(v);
38                }
39            }
40        }
41    }
42}
43
44pub fn chain<T: 'static>(input: Vec<Box<dyn Iterator<Item = Result<T, Error>>>>) -> Box<dyn Iterator<Item = Result<T, Error>>>  {
45    Box::new(Chain {
46        input,
47        cur_idx: 0,
48        iter_finished: false,
49        iter_err: None
50    })
51}
52
53#[cfg(test)]
54mod tests {
55    use crate::utils::{extract_value_from_result_vec, generate_okok_iterator};
56
57    use super::*;
58
59    #[test]
60    fn test1() {
61        let mut input = Vec::new();
62
63        let v = vec![1,2,3];
64        let ret1 = generate_okok_iterator(v);
65        input.push(ret1);
66
67        let v = vec![2,4,6];
68        let ret2 = generate_okok_iterator(v);
69        input.push(ret2);
70
71        let chain = chain(input);
72
73        let ret = extract_value_from_result_vec(chain.collect::<Vec<_>>());
74        assert!(ret.1.is_none());
75        assert_eq!(vec![1,2,3,2,4,6], ret.0);
76    }
77}