more_itertools/itertools/
islice.rs1use 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 continue;
39 },
40 Err(err_v_ret) => {
41 self.iter_finished = true;
42 return Some(Err(err_v_ret.clone())); }
44 }
45 } else {
46 self.iter_finished = true;
47 return None;
48 }
49 }
50 self.skipped_start = true;
51 }
52
53 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}