more_itertools/windowing/
windowed_complete.rs

1use crate::error::Error;
2use crate::error;
3
4pub struct WindowedComplete<T>
5where 
6T: Clone + 'static
7 {
8    buf: Vec<T>,
9    iter: Box<dyn Iterator<Item=Result<T,Error>>>,
10    n: usize,
11    cur: usize,
12    iter_finished: bool,
13    upstream_error: Option<Error>
14}
15
16impl<T> Iterator for WindowedComplete<T> 
17where 
18T: Clone + 'static
19{
20    type Item = Result<(Vec<T>, Vec<T>, Vec<T>), Error>;
21
22    fn next(&mut self) -> Option<Self::Item> {
23        if self.iter_finished {
24            return None;
25        }
26
27        if self.n > self.buf.len() {
28            self.iter_finished = true;
29            return Some(Err(error::value_error("[windowed_complete:n must be <= len(seq)]".to_string())));
30        }
31
32        if let Some(v_upstream_error) = &self.upstream_error {
33            self.iter_finished = true;
34            return Some(Err(v_upstream_error.clone()));
35        }
36
37        if self.cur + self.n > self.buf.len() {
38            return None;
39        }
40
41        let mut beginning = Vec::new();
42        for v in self.buf[0..self.cur].iter() {
43            beginning.push(v.clone());
44        }
45
46        let mut middle = Vec::new();
47        for v in self.buf[self.cur..self.cur+self.n].iter() {
48            middle.push(v.clone());
49        }
50
51        let mut end = Vec::new();
52        for v in self.buf[(self.cur+self.n)..self.buf.len()].iter() {
53            end.push(v.clone());
54        }
55
56        self.cur += 1;
57
58        return Some(Ok((beginning, middle, end)));
59    }
60}
61
62
63/// https://more-itertools.readthedocs.io/en/v10.2.0/api.html#more_itertools.windowed_complete
64pub fn windowed_complete<T>(iter: Box<dyn Iterator<Item=Result<T,Error>>>, n: usize) -> Box<dyn Iterator<Item=Result<(Vec<T>, Vec<T>, Vec<T>), Error>>>
65where
66T: Clone + 'static
67{
68    let mut ret = WindowedComplete {
69        buf: Vec::new(),
70        iter,
71        n,
72        cur: 0,
73        iter_finished: false,
74        upstream_error: None
75    };
76
77    loop {
78        if let Some(item) = ret.iter.next() {
79            match item {
80                Ok(ok_item) => {
81                    ret.buf.push(ok_item);
82                },
83                Err(err_item) => {
84                    ret.upstream_error = Some(err_item);
85                    break;
86                }
87            }
88        } else {
89            break;
90        }
91    }
92
93    return Box::new(ret);
94}
95
96#[cfg(test)]
97mod tests {
98    use crate::utils::generate_okok_iterator;
99
100    use super::*;
101
102    #[test]
103    fn test1() {
104        let v = generate_okok_iterator(vec![0,1,2,3,4,5,6]);
105
106        let mut wc = windowed_complete(v, 3);
107
108        match wc.next() {
109            None => { assert!(false); }
110            Some(v) => {
111                match v {
112                    Ok(v2) => {
113                        assert_eq!(v2.0, vec![]);
114                        assert_eq!(v2.1, vec![0, 1, 2]);
115                        assert_eq!(v2.2, vec![3, 4, 5, 6]);
116                    }
117                    Err(_) => { assert!(false); }
118                }
119            }
120        }
121
122        match wc.next() {
123            None => { assert!(false); }
124            Some(v) => {
125                match v {
126                    Ok(v2) => {
127                        assert_eq!(v2.0, vec![0]);
128                        assert_eq!(v2.1, vec![1, 2, 3]);
129                        assert_eq!(v2.2, vec![4, 5, 6]);
130                    }
131                    Err(_) => { assert!(false); }
132                }
133            }
134        }
135
136        match wc.next() {
137            None => { assert!(false); }
138            Some(v) => {
139                match v {
140                    Ok(v2) => {
141                        assert_eq!(v2.0, vec![0, 1]);
142                        assert_eq!(v2.1, vec![2, 3, 4]);
143                        assert_eq!(v2.2, vec![5, 6]);
144                    }
145                    Err(_) => { assert!(false); }
146                }
147            }
148        }
149
150        match wc.next() {
151            None => { assert!(false); }
152            Some(v) => {
153                match v {
154                    Ok(v2) => {
155                        assert_eq!(v2.0, vec![0, 1, 2]);
156                        assert_eq!(v2.1, vec![3, 4, 5]);
157                        assert_eq!(v2.2, vec![6]);
158                    }
159                    Err(_) => { assert!(false); }
160                }
161            }
162        }
163
164        match wc.next() {
165            None => { assert!(false); }
166            Some(v) => {
167                match v {
168                    Ok(v2) => {
169                        assert_eq!(v2.0, vec![0, 1, 2, 3]);
170                        assert_eq!(v2.1, vec![4, 5, 6]);
171                        assert_eq!(v2.2, vec![]);
172                    }
173                    Err(_) => { assert!(false); }
174                }
175            }
176        }
177
178        match wc.next() {
179            None => { assert!(true); }
180            Some(_) => { assert!(false); }
181        }
182    }
183}