more_itertools/selecting/
map_except.rs1use crate::error::Error;
2use crate::error;
3
4pub struct MapExcept<I, T> {
5 iter: Box<dyn Iterator<Item = Result<I,Error>>>,
7 func: fn(item: &I) -> Result<T, Error>,
8 acceptable_except: Vec<error::Kind>,
9 error: Option<Error>,
10 iter_finished: bool
11}
12
13impl<I, T> Iterator for MapExcept<I, T> {
14 type Item = Result<T, Error>;
15
16 fn next(&mut self) -> Option<Self::Item> {
17 loop {
18 if self.iter_finished {
19 return None;
20 }
21
22 let ret = self.iter.next();
23 if let Some(v) = ret {
24 if v.is_err() {
25 self.error = Some(v.as_ref().err().unwrap().clone());
26 self.iter_finished = true;
27 return Some(Err(v.as_ref().err().unwrap().clone()));
28 }
29
30 let val_result = (self.func)(v.as_ref().ok().unwrap());
31 match val_result {
32 Ok(ok_val_result) => {
33 return Some(Ok(ok_val_result));
34 },
35 Err(err_val_result) => {
36 if self.acceptable_except.contains(&err_val_result.kind()) {
37 continue;
38 } else {
39 self.iter_finished = true;
40 return Some(Err(error::any_error(err_val_result.kind(),
41 "[map_except] ".to_string() + err_val_result.message().unwrap())));
42 }
43 }
44 }
45 } else {
46 self.iter_finished = true;
47 return None
48 }
49
50
51 }
52
53 }
79
80}
81
82pub fn map_except<I, T>(iter: Box<dyn Iterator<Item = Result<I,Error>>>,
83 func: fn(item: &I) -> Result<T, Error>,
84 acceptable_except: Vec<error::Kind>) -> Box<dyn Iterator<Item = Result<T, Error>>>
85where
86I: 'static,
87T: 'static
88{
89 Box::new(MapExcept {
90 iter,
91 func,
92 acceptable_except,
93 error: None,
94 iter_finished: false
95 })
96}
97
98#[cfg(test)]
99mod tests {
100 use crate::utils::generate_okok_iterator;
101 use crate::utils::generate_okokerr_iterator;
102
103 use super::*;
104
105 #[test]
106 fn test1() {
107 let iterable = vec!["1", "2", "three", "4", "5"];
108 let mut fm = map_except(generate_okok_iterator(iterable),
109 |x| {
110 let ret = x.parse::<i32>();
111 match ret {
112 Ok(v) => { return Ok(v); },
113 Err(e) => { return Err(error::value_error(e.to_string())); }
114 }
115 },
116 vec![error::Kind::ValueError]
117 );
118
119 assert_eq!(1, fm.next().unwrap().ok().unwrap());
120 assert_eq!(2, fm.next().unwrap().ok().unwrap());
121 assert_eq!(4, fm.next().unwrap().ok().unwrap());
122 assert_eq!(5, fm.next().unwrap().ok().unwrap());
123 assert_eq!(None, fm.next());
124 assert_eq!(None, fm.next());
125 }
126
127
128 #[test]
129 fn test2() {
130 let iterable = vec!["1", "2", "three", "4", "5"];
131 let mut fm = map_except(generate_okok_iterator(iterable),
132 |x| {
133 let ret = x.parse::<i32>();
134 match ret {
135 Ok(v) => { return Ok(v); },
136 Err(e) => { return Err(error::value_error(e.to_string())); }
137 }
138 },
139 vec![]
140 );
141
142 assert_eq!(1, fm.next().unwrap().ok().unwrap());
143 assert_eq!(2, fm.next().unwrap().ok().unwrap());
144 assert_eq!(error::Kind::ValueError, fm.next().unwrap().err().unwrap().kind());
145 assert_eq!(None, fm.next());
146 assert_eq!(None, fm.next());
147 }
148
149 #[test]
150 fn test3() {
151 let iterable = vec!["1", "2"];
152 let mut fm = map_except(generate_okokerr_iterator(iterable, error::overflow_error("[test]".to_string())),
153 |x| {
154 let ret = x.parse::<i32>();
155 match ret {
156 Ok(v) => { return Ok(v); },
157 Err(e) => { return Err(error::value_error(e.to_string())); }
158 }
159 },
160 vec![]
161 );
162
163 assert_eq!(1, fm.next().unwrap().ok().unwrap());
164 assert_eq!(2, fm.next().unwrap().ok().unwrap());
165 assert_eq!(error::Kind::OverflowError, fm.next().unwrap().err().unwrap().kind());
166 }
167}