more_itertools/combining/
zip_equal.rs1use 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 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}