more_itertools/windowing/
substrings_indexes.rs

1use crate::error::Error;
2
3pub struct SubstringsIndexes<T> {
4    string_len: usize,
5    substring_len: usize,
6    cur: usize,
7    vec: Vec<T>,
8    reverse: bool,
9    upstream_error: Option<Error>,
10    iter_finished: bool,
11}
12
13impl<T> Iterator for SubstringsIndexes<T>
14where
15T: Clone
16{
17    type Item = Result<(Vec<T>, usize, usize), Error>;
18
19    fn next(&mut self) -> Option<Self::Item> {
20        if self.iter_finished {
21            return None;
22        }
23
24        if let Some(v_upstream_error) = &self.upstream_error {
25            self.iter_finished = true;
26            return Some(Err(v_upstream_error.clone()));
27        }
28
29        if !self.reverse {
30            loop {
31                if self.substring_len > self.vec.len() {
32                    return None;
33                }
34        
35                if self.cur + self.substring_len > self.vec.len() {
36                    self.cur = 0;
37                    self.substring_len += 1;
38                    continue;
39                } else {
40                    let mut ret = Vec::new();
41                    for ele in &self.vec.as_slice()[self.cur..self.cur+self.substring_len] {
42                        ret.push(ele.clone())
43                    }
44                    let cur = self.cur;
45                    self.cur += 1;
46
47                    return Some(Ok((ret, cur, cur+self.substring_len)));
48                }
49            }
50        } else {
51            loop {
52                if self.substring_len <= 0 {
53                    return None;
54                }
55    
56                if self.cur == usize::MAX {
57                    self.substring_len -= 1;
58                    self.cur = self.string_len - self.substring_len;
59                    continue;
60                } else {
61                    let mut ret = Vec::new();
62                    for ele in &self.vec.as_slice()[self.cur..self.cur+self.substring_len] {
63                        ret.push(ele.clone())
64                    }
65                    let cur = self.cur;
66                    self.cur -= 1;
67
68                    return Some(Ok((ret, cur, cur+self.substring_len)));
69                }
70            }
71        }
72    }
73}
74
75
76pub fn substrings_indexes<T>(mut iter: Box<dyn Iterator<Item = Result<T,Error>>>, reverse: bool) -> Box<dyn Iterator<Item = Result<(Vec<T>,usize,usize),Error>>> 
77where
78T: Clone + 'static
79{
80    let mut upstream_error: Option<Error> = None;
81
82    let mut vec = Vec::new();
83    loop {
84        if let Some(item) = iter.next() {
85            match item {
86                Ok(ok_item) => {
87                    vec.push(ok_item);
88                },
89                Err(err_item) => {
90                    upstream_error = Some(err_item);
91                    break;
92                }
93            }
94        } else {
95            break;
96        }
97    }
98
99    let mut ret = SubstringsIndexes {
100        string_len: vec.len(),
101        substring_len: 1,
102        cur: 0,
103        vec,
104        reverse,
105        upstream_error,
106        iter_finished: false,
107    };
108
109    if ret.reverse {
110        ret.substring_len = ret.string_len;
111        ret.cur = ret.string_len - ret.substring_len;
112    }
113
114    return Box::new(ret);
115}
116
117#[cfg(test)]
118mod tests {
119    use crate::{error, utils::{generate_okok_iterator, generate_okokerr_iterator}};
120
121    use super::*;
122
123    #[test]
124    fn test1() {
125        let v = generate_okok_iterator("more".to_string().chars().collect());
126        let mut ssi = substrings_indexes(v, false);
127
128        assert_eq!(Some((vec!['m'], 0 as usize, 1 as usize)), ssi.next().unwrap().ok());
129        assert_eq!(Some((vec!['o'], 1 as usize, 2 as usize)), ssi.next().unwrap().ok());
130        assert_eq!(Some((vec!['r'], 2 as usize, 3 as usize)), ssi.next().unwrap().ok());
131        assert_eq!(Some((vec!['e'], 3 as usize, 4 as usize)), ssi.next().unwrap().ok());
132        assert_eq!(Some((vec!['m', 'o'], 0 as usize, 2 as usize)), ssi.next().unwrap().ok());
133        assert_eq!(Some((vec!['o', 'r'], 1 as usize, 3 as usize)), ssi.next().unwrap().ok());
134        assert_eq!(Some((vec!['r', 'e'], 2 as usize, 4 as usize)), ssi.next().unwrap().ok());
135        assert_eq!(Some((vec!['m', 'o', 'r'], 0 as usize, 3 as usize)), ssi.next().unwrap().ok());
136        assert_eq!(Some((vec!['o', 'r', 'e'], 1 as usize, 4 as usize)), ssi.next().unwrap().ok());
137        assert_eq!(Some((vec!['m', 'o', 'r', 'e'], 0 as usize, 4 as usize)), ssi.next().unwrap().ok());
138        assert_eq!(None, ssi.next());
139    }
140
141    #[test]
142    fn test2() {
143        let v = generate_okok_iterator("more".to_string().chars().collect());
144        let mut ssi = substrings_indexes(v, true);
145
146        assert_eq!(Some((vec!['m', 'o', 'r', 'e'], 0 as usize, 4 as usize)), ssi.next().unwrap().ok());
147        assert_eq!(Some((vec!['o', 'r', 'e'], 1 as usize, 4 as usize)), ssi.next().unwrap().ok());
148        assert_eq!(Some((vec!['m', 'o', 'r'], 0 as usize, 3 as usize)), ssi.next().unwrap().ok());
149        assert_eq!(Some((vec!['r', 'e'], 2 as usize, 4 as usize)), ssi.next().unwrap().ok());
150        assert_eq!(Some((vec!['o', 'r'], 1 as usize, 3 as usize)), ssi.next().unwrap().ok());
151        assert_eq!(Some((vec!['m', 'o'], 0 as usize, 2 as usize)), ssi.next().unwrap().ok());
152        assert_eq!(Some((vec!['e'], 3 as usize, 4 as usize)), ssi.next().unwrap().ok());
153        assert_eq!(Some((vec!['r'], 2 as usize, 3 as usize)), ssi.next().unwrap().ok());
154        assert_eq!(Some((vec!['o'], 1 as usize, 2 as usize)), ssi.next().unwrap().ok());
155        assert_eq!(Some((vec!['m'], 0 as usize, 1 as usize)), ssi.next().unwrap().ok());
156        assert_eq!(None, ssi.next());
157    }
158
159    #[test]
160    fn test3() {
161        let v = generate_okokerr_iterator("more".to_string().chars().collect(), error::overflow_error("[test]".to_string()));
162        let mut ssi = substrings_indexes(v, true);
163        assert_eq!(error::Kind::OverflowError, ssi.next().unwrap().err().unwrap().kind());
164    }
165}