more_itertools/itertools/
islice.rs

1use crate::error::Error;
2use crate::error;
3
4pub struct Islice<T> {
5    iter: Box<dyn Iterator<Item = Result<T,Error>>>,
6    start: usize,
7    stop: usize,
8    step: usize,
9    cur: usize,
10    skipped_start: bool,
11    iter_finished: bool,
12    emitted_first: bool
13}
14
15impl<T> Iterator for Islice<T> {
16    type Item = Result<T, Error>;
17
18    fn next(&mut self) -> Option<Self::Item> {
19        if self.iter_finished {
20            return None;
21        }
22
23        if self.stop <= self.start {
24            self.iter_finished = true;
25            return None;
26        }
27
28        let mut ret = None;
29
30        if !self.skipped_start {
31            while self.cur < self.start {
32                ret = self.iter.next();
33                self.cur += 1;
34                if let Some(ref v_ret) = ret {
35                    match v_ret {
36                        Ok(_) => {
37                            //return Some(Ok(ok_v_ret));
38                            continue;
39                        },
40                        Err(err_v_ret) => {
41                            self.iter_finished = true;
42                            return Some(Err(err_v_ret.clone())); // upstream error
43                        }
44                    }
45                } else {
46                    self.iter_finished = true;
47                    return None;
48                }
49            }
50            self.skipped_start = true;
51        } 
52
53        //let mut ret = None;
54        if self.emitted_first {
55            if (usize::MAX - self.cur) < self.step {
56                self.iter_finished = true;
57                return Some(Err(error::overflow_error(String::from("[islice:cur overflow]"))));
58            }
59            self.cur += self.step;
60            if self.cur >= self.stop {
61                self.iter_finished = true;
62                return None;
63            }
64            for _ in 0..self.step {
65                ret = self.iter.next();
66            }
67        } else {
68            ret = self.iter.next();
69            self.emitted_first = true;
70        }
71        
72        match ret {
73            None => {return None;}
74            Some(v) => { 
75                match v {
76                    Ok(ok_v) => {
77                        return Some(Ok(ok_v))
78                    },
79                    Err(err_v) => {
80                        return Some(Err(err_v));
81                    }
82                }
83            }
84        }
85
86    }
87}
88
89
90pub fn islice<T>(iter: Box<dyn Iterator<Item = Result<T,Error>>>, start: usize, stop: usize, step: usize) -> Box<dyn Iterator<Item=Result<T, Error>>>
91where
92    T: 'static
93{
94    Box::new(Islice {
95        iter,
96        start,
97        stop,
98        step,
99        cur: 0,
100        skipped_start: false,
101        iter_finished: false,
102        emitted_first: false
103    })
104}
105
106
107#[cfg(test)]
108mod tests {
109    use crate::utils::{extract_value_from_result_vec, generate_okok_iterator, generate_okokerr_iterator};
110
111    use super::*;
112
113    #[test]
114    fn test1() {
115        let i = islice(generate_okok_iterator(vec![0,1,2,3,4]), 3, 10, 1);
116        let ret = extract_value_from_result_vec(i.collect::<Vec<_>>());
117        assert_eq!(vec![3,4], ret.0);
118
119        let mut i2 = islice(generate_okok_iterator(vec![0,1,2,3,4,5,6]), 7, 10, 1);
120        assert_eq!(None, i2.next());
121
122        let v3  = vec![0,1,2,3,4,5,6,7,8,9,10];
123        let i3 = islice(generate_okok_iterator(v3), 3, 11, 3);
124        let ret = extract_value_from_result_vec(i3.collect::<Vec<_>>());
125        assert_eq!(vec![3,6,9], ret.0);
126
127    }
128
129    #[test]
130    fn test2() {
131        let v3  = generate_okokerr_iterator(vec![0,1,2,3,4,5,6,7,8,9,10], error::overflow_error("[test]".to_string()));
132        let mut i3 = islice(v3, 9, 15, 3);
133        assert_eq!(Some(Ok(9)), i3.next());
134        assert_eq!(error::Kind::OverflowError, i3.next().unwrap().err().unwrap().kind());
135        assert_eq!(None, i3.next());
136    }
137}