more_itertools/windowing/
substrings.rs

1use crate::error::Error;
2
3pub struct Substrings<T> 
4where
5T: Clone
6{
7    iter: Box<dyn Iterator<Item = Result<T,Error>>>,
8    substring_len: usize,
9    cur: usize,
10    vec: Vec<T>,
11    upstream_error: Option<Error>,
12    iter_finished: bool,
13}
14
15
16impl<T> Iterator for Substrings<T> 
17where 
18T: Clone
19{
20    type Item = Result<Vec<T>, Error>;
21
22    fn next(&mut self) -> Option<Self::Item> {
23
24        if self.iter_finished {
25            return None;
26        }
27
28        if let Some(v_upstream_error) = &self.upstream_error {
29            self.iter_finished = true;
30            return Some(Err(v_upstream_error.clone()));
31        }
32
33        loop {
34            if self.substring_len > self.vec.len() {
35                return None;
36            }
37    
38            if self.cur + self.substring_len > self.vec.len() {
39                self.cur = 0;
40                self.substring_len += 1;
41                continue;
42            } else {
43                let mut ret = Vec::new();
44                for ele in self.vec[self.cur..self.cur+self.substring_len].iter() {
45                    ret.push(ele.clone())
46                }
47                self.cur += 1;
48                return Some(Ok(ret));
49            }
50        }
51    }
52}
53
54
55pub fn substrings<T>(iter: Box<dyn Iterator<Item = Result<T,Error>>>) -> Box<dyn Iterator<Item = Result<Vec<T>, Error>>>
56where
57T: Clone + 'static
58{
59    let mut ret = Substrings {
60        iter,
61        substring_len: 1,
62        cur: 0,
63        vec: Vec::new(),
64        upstream_error: None,
65        iter_finished: false
66    };
67
68    loop {
69        if let Some(item) = ret.iter.next() {
70            match item {
71                Ok(ok_item) => {
72                    ret.vec.push(ok_item);
73                },
74                Err(err_item) => {
75                    ret.upstream_error = Some(err_item);
76                    break;
77                }
78            }
79        } else {
80            break;
81        }
82    }
83
84    return Box::new(ret);
85}
86
87
88#[cfg(test)]
89mod tests {
90    use crate::utils::generate_okok_iterator;
91
92    use super::*;
93
94    #[test]
95    fn test1() {
96        let v = vec![1,2,3,4];
97        let mut ss = substrings(generate_okok_iterator(v));
98
99        assert_eq!(Some(vec![1]), ss.next().unwrap().ok());
100        assert_eq!(Some(vec![2]), ss.next().unwrap().ok());
101        assert_eq!(Some(vec![3]), ss.next().unwrap().ok());
102        assert_eq!(Some(vec![4]), ss.next().unwrap().ok());
103
104        assert_eq!(Some(vec![1,2]), ss.next().unwrap().ok());
105        assert_eq!(Some(vec![2,3]), ss.next().unwrap().ok());
106        assert_eq!(Some(vec![3,4]), ss.next().unwrap().ok());
107
108        assert_eq!(Some(vec![1,2,3]), ss.next().unwrap().ok());
109        assert_eq!(Some(vec![2,3,4]), ss.next().unwrap().ok());
110
111        assert_eq!(Some(vec![1,2,3,4]), ss.next().unwrap().ok());
112
113        assert_eq!(None, ss.next());
114        assert_eq!(None, ss.next());
115    }
116}