more_itertools/selecting/
map_except.rs

1use crate::error::Error;
2use crate::error;
3
4pub struct MapExcept<I, T> {
5    // cur: usize,
6    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        // loop {
54        //     let ret = self.iter.next();
55        //     match ret {
56        //         None => { return None; }
57        //         Some(v) => {
58        //             let res_func_ret = (self.func)(&v);
59        //             match res_func_ret {
60        //                 Ok(func_ret) => {
61        //                     return Some(Ok(func_ret));
62        //                 },
63        //                 Err(e) => {
64        //                     if self.acceptable_except.contains(&e.kind()) {
65        //                         continue;
66        //                     } else {
67        //                         self.failed = true;
68        //                         match e.message() {
69        //                             None => { return Some(Err(error::any_error(e.kind(), "func failed".to_string()))); }
70        //                             Some(m) => { return Some(Err(error::any_error(e.kind(), "func failed: ".to_string()+m))); }
71        //                         }
72        //                     }
73        //                 }
74        //             }
75        //         }
76        //     }
77        // }
78    }
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}