more_itertools/combining/
zip_offset.rs1use std::collections::VecDeque;
2use crate::error::Error;
3
4use crate::selecting::take::take;
5
6
7pub struct ZipOffset<T> {
8 buf: VecDeque<T>,
9 buf2: VecDeque<Option<T>>,
10 iter_vec: Vec<Box<dyn Iterator<Item = Result<T,Error>>>>,
11 iter_finished: bool,
12 longest: bool,
13 fillvalue: T
14}
15
16impl<T> Iterator for ZipOffset<T>
17where
18T: Clone + 'static
19{
20 type Item = Result<Vec<T>,Error>;
21
22 fn next(&mut self) -> Option<Self::Item> {
23 loop {
24 if self.iter_finished {
25 return None;
26 }
27
28 if self.buf.len() > 0 {
29 let mut ret = Vec::<T>::new();
31 while self.buf.len() > 0 {
32 ret.push(self.buf.pop_front().unwrap());
33 }
34 return Some(Ok(ret));
35 }
36
37 assert_eq!(0, self.buf2.len());
38
39 for i in self.iter_vec.iter_mut() {
40 if let Some(v) = i.next() {
41 match v {
42 Ok(ok_v) => {
43 self.buf2.push_back(Some(ok_v));
44 },
45 Err(err_v) => {
46 self.iter_finished = true;
47 return Some(Err(err_v));
48 }
49 }
50 } else {
51 self.buf2.push_back(None);
52 }
53 }
54
55 if self.longest {
56 if self.buf2.iter().all(|x| match x {
57 None => { return true; },
58 Some(_) => { return false; }
59 }) {
60 self.iter_finished = true;
61 } else {
62 while self.buf2.len() > 0 {
63 match self.buf2.pop_front() {
64 None => {
65 self.buf.push_back(self.fillvalue.clone());
66 },
67 Some(v) => {
68 if !v.is_none() {
69 self.buf.push_back(v.unwrap());
70 } else {
71 self.buf.push_back(self.fillvalue.clone());
72 }
73 }
74 }
75 }
76 }
77 } else {
78 if self.buf2.iter().any(|x| match x {
79 None => { return true; },
80 Some(_) => { return false; }
81 }) {
82 self.iter_finished = true;
83 } else {
84 while self.buf2.len() > 0 {
85 self.buf.push_back(self.buf2.pop_front().unwrap().unwrap());
86 }
87 }
88 }
89 }
90 }
91}
92
93pub fn zip_offset<T>(mut iter_vec: Vec<Box<dyn Iterator<Item = Result<T,Error>>>>,
94 offsets_vec: Vec<usize>,
95 longest: bool,
96 fillvalue: T) -> Box<dyn Iterator<Item = Result<Vec<T>,Error>>>
97where T: Clone + 'static
98{
99 for (index, offset) in offsets_vec.iter().enumerate() {
100 take(iter_vec.get_mut(index).as_mut().unwrap(), *offset);
101 }
102
103 return Box::new(ZipOffset {
104 buf: VecDeque::new(),
105 buf2: VecDeque::new(),
106 iter_vec,
107 iter_finished: false,
108 longest,
109 fillvalue
110 });
111}
112
113
114
115#[cfg(test)]
116mod tests {
117
118 use crate::{error, utils::{extract_value_from_result_vec, generate_okok_iterator, generate_okokerr_iterator}};
119
120 use super::*;
121
122 #[test]
123 fn test1() {
124 let v1 = "0123".chars().collect::<Vec<_>>();
125 let v2 = "abcdef".chars().collect::<Vec<_>>();
126
127 let mut v = Vec::new();
128 v.push(generate_okok_iterator(v1));
129 v.push(generate_okok_iterator(v2));
130
131 let ret = zip_offset(v, vec![0,1], false, '9');
132 let ret2 = extract_value_from_result_vec(ret.collect::<Vec<_>>());
133 assert_eq!(vec![vec!['0', 'b'], vec!['1', 'c'], vec!['2', 'd'], vec!['3', 'e']], ret2.0);
134
135 let v1 = "0123".chars().collect::<Vec<_>>();
138 let v2 = "abcdef".chars().collect::<Vec<_>>();
139
140 let mut v = Vec::new();
141 v.push(generate_okok_iterator(v2));
142 v.push(generate_okok_iterator(v1));
143
144 let ret = zip_offset(v, vec![0,1], false, '9');
145 let ret2 = extract_value_from_result_vec(ret.collect::<Vec<_>>());
146 assert_eq!(vec![vec!['a', '1'], vec!['b', '2'], vec!['c', '3']], ret2.0);
147 assert_eq!(None, ret2.1);
148 }
149
150 #[test]
151 fn test2() {
152 let v1 = "0123".chars().collect::<Vec<_>>();
153 let v2 = "abcdef".chars().collect::<Vec<_>>();
154
155 let mut v = Vec::new();
156 v.push(generate_okok_iterator(v1));
157 v.push(generate_okok_iterator(v2));
158
159 let ret = zip_offset(v, vec![0,1], true, '9');
160 let ret2 = extract_value_from_result_vec(ret.collect::<Vec<_>>());
161 assert_eq!(vec![vec!['0', 'b'], vec!['1', 'c'], vec!['2', 'd'], vec!['3', 'e'], vec!['9', 'f']], ret2.0);
162 }
163
164 #[test]
165 fn test3() {
166 let v1 = "0123".chars().collect::<Vec<_>>();
167 let v2 = "abcdef".chars().collect::<Vec<_>>();
168
169 let mut v = Vec::new();
170 v.push(generate_okokerr_iterator(v1, error::overflow_error("[test]".to_string())));
171 v.push(generate_okok_iterator(v2));
172
173 let ret = zip_offset(v, vec![0,1], false, '9');
174 let ret2 = extract_value_from_result_vec(ret.collect::<Vec<_>>());
175 assert_eq!(vec![vec!['0', 'b'], vec!['1', 'c'], vec!['2', 'd'], vec!['3', 'e']], ret2.0);
176 assert_eq!(error::Kind::OverflowError, ret2.1.unwrap().kind());
177
178
179 let v1 = "0123".chars().collect::<Vec<_>>();
180 let v2 = "abcdef".chars().collect::<Vec<_>>();
181
182 let mut v = Vec::new();
183 v.push(generate_okok_iterator(v1));
184 v.push(generate_okokerr_iterator(v2, error::overflow_error("[test]".to_string())));
185
186 let ret = zip_offset(v, vec![0,1], false, '9');
187 let ret2 = extract_value_from_result_vec(ret.collect::<Vec<_>>());
188 assert_eq!(vec![vec!['0', 'b'], vec!['1', 'c'], vec!['2', 'd'], vec!['3', 'e']], ret2.0);
189 assert_eq!(None, ret2.1);
190 }
191}
192