more_itertools/combining/
zip_offset.rs

1use 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 ret = self.buf.pop_front().unwrap();
30                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        // =================================================
136
137        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