more_itertools/combining/
zip_equal.rs

1use std::collections::VecDeque;
2use crate::error;
3use crate::error::Error;
4
5pub struct ZipEqual<T> {
6    buf: VecDeque<T>,
7    buf2: VecDeque<Option<T>>,
8    iter_vec: Vec<Box<dyn Iterator<Item = Result<T,Error>>>>,
9    iter_finished: bool
10}
11
12impl<T> Iterator for ZipEqual<T> 
13where
14T: Clone + 'static
15{
16    type Item = Result<Vec<T>, Error>;
17
18    fn next(&mut self) -> Option<Self::Item> {
19        loop {
20            if self.iter_finished {
21                return None;
22            }
23
24            // if self.buf.len() > 0 {
25            //     let ret = self.buf.pop_front().unwrap();
26            //     return Some(ret);
27            // }
28
29            assert_eq!(0, self.buf2.len());
30
31            for i in self.iter_vec.iter_mut() {
32                if let Some(v) = i.next() {
33                    match v {
34                        Ok(ok_v) => {
35                            self.buf2.push_back(Some(ok_v));
36                        },
37                        Err(err_v) => {
38                            self.iter_finished = true;
39                            return Some(Err(err_v));
40                        }
41                    }
42                } else {
43                    self.buf2.push_back(None);
44                }
45            }
46
47            if self.buf2.iter().all(|x| match x {
48                None => { return true; },
49                Some(_) => { return false; }
50            }) {
51                self.iter_finished = true;
52            } else {
53                while self.buf2.len() > 0 {
54                    match self.buf2.front() {
55                        None => {
56                            self.buf2.pop_front();
57                            continue;
58                        },
59                        Some(v) => {
60                            match v {
61                                None => {
62                                    self.buf2.pop_front();
63                                    continue;
64                                },
65                                Some(v2) => {
66                                    self.buf.push_back(v2.clone());
67                                    self.buf2.pop_front();
68                                }
69                            }
70                        }
71                    }
72                }
73                if self.buf.len() != self.iter_vec.len() {
74                    self.iter_finished = true;
75                    return Some(Err(error::any_error(error::Kind::IteratorError, "Iterables have different lengths".to_string())));
76                } else {
77                    let mut ret = Vec::new();
78                    while self.buf.len() > 0 {
79                        ret.push(self.buf.pop_front().unwrap());
80                    }
81                    return Some(Ok(ret));
82                }
83            }
84        }   
85    }
86}
87
88pub fn zip_equal<T>(iter_vec: Vec<Box<dyn Iterator<Item = Result<T,Error>>>>) -> Box<dyn Iterator<Item = Result<Vec<T>,Error>>> 
89where T: Clone + 'static
90{
91    Box::new(ZipEqual {
92        buf: VecDeque::new(),
93        buf2: VecDeque::new(),
94        iter_vec,
95        iter_finished: false
96    })
97}
98
99#[cfg(test)]
100mod tests {
101
102    use crate::utils::{generate_okok_iterator, generate_okokerr_iterator};
103
104    use super::*;
105
106    #[test]
107    fn test1() {
108        let mut v = Vec::new();
109        v.push(generate_okok_iterator(vec![1,2,3]));
110        v.push(generate_okok_iterator(vec![4,5,6]));
111        v.push(generate_okok_iterator(vec![6,7,8]));
112
113        let mut iter = zip_equal(v);
114
115        assert_eq!(Some(Ok(vec![1, 4, 6])), iter.next());
116        assert_eq!(Some(Ok(vec![2, 5, 7])), iter.next());
117        assert_eq!(Some(Ok(vec![3, 6, 8])), iter.next());
118        assert_eq!(None, iter.next());
119    }
120
121    #[test]
122    fn test2() {
123        let mut v = Vec::new();
124        v.push(generate_okok_iterator(vec![1,2,3]));
125        v.push(generate_okok_iterator(vec![4,5]));
126        v.push(generate_okok_iterator(vec![6,7,8]));
127
128        let mut iter = zip_equal(v);
129
130        assert_eq!(Some(Ok(vec![1, 4, 6])), iter.next());
131        assert_eq!(Some(Ok(vec![2, 5, 7])), iter.next());
132        assert_eq!(error::Kind::IteratorError, iter.next().unwrap().err().unwrap().kind());
133        assert_eq!(None, iter.next());
134    }
135
136    #[test]
137    fn test3() {
138        let mut v = Vec::new();
139        v.push(generate_okok_iterator(vec![1,2,3]));
140        v.push(generate_okokerr_iterator(vec![4,5], error::overflow_error("[test]".to_string())));
141        v.push(generate_okok_iterator(vec![6,7,8]));
142
143        let mut iter = zip_equal(v);
144
145        assert_eq!(Some(Ok(vec![1, 4, 6])), iter.next());
146        assert_eq!(Some(Ok(vec![2, 5, 7])), iter.next());
147        assert_eq!(error::Kind::OverflowError, iter.next().unwrap().err().unwrap().kind());
148        assert_eq!(None, iter.next());
149    }
150
151}