more_itertools/itertools/
map.rs

1use crate::error::{self, Error};
2
3struct Map<T, J> {
4    iter: Box<dyn Iterator<Item = Result<T,Error>>>,
5    pred: fn(T) -> Result<J, Error>,
6    iter_finished: bool,
7    iter_error: Option<Error>
8}
9
10impl<T,J> Iterator for Map<T, J>
11{
12    type Item = Result<J, Error>;
13
14    fn next(&mut self) -> Option<Self::Item> {
15        if self.iter_finished {
16            return None;
17        }
18
19        if self.iter_error.is_some() {
20            return Some(Err(self.iter_error.as_ref().unwrap().clone()));
21        }
22
23        let _next = self.iter.next();
24        if let Some(v) = _next {
25            if let Ok(v2) = v {
26                let j = (self.pred)(v2);
27                if j.is_err() {
28                    self.iter_error = Some(j.as_ref().err().unwrap().clone());
29                    self.iter_finished = true;
30                }
31                return Some(j);
32            } else {
33                self.iter_finished = true;
34                return Some(Err(v.err().unwrap()));
35            }
36        } else {
37            self.iter_finished = true;
38            return None;
39        }
40    }
41}
42
43pub fn map<T: 'static, J: 'static>(iter: Box<dyn Iterator<Item=Result<T,Error>>>, pred: fn(T)->Result<J, Error>) -> Box<dyn Iterator<Item=Result<J, Error>>> 
44{
45    return Box::new(Map {
46        iter,
47        pred: pred,
48        iter_finished: false,
49        iter_error: None
50    });
51}
52
53
54struct Map2<T0, T1, J> {
55    iter0: Box<dyn Iterator<Item=Result<T0,Error>>>,
56    iter1: Box<dyn Iterator<Item=Result<T1,Error>>>,
57    pred: fn(&T0, &T1)->Result<J, Error>,
58    iter_finished: bool,
59    iter_error: Option<Error>
60}
61
62impl<T0, T1, J> Iterator for Map2<T0, T1, J>
63{
64    type Item = Result<J, Error>;
65
66    fn next(&mut self) -> Option<Self::Item> {
67        if self.iter_finished {
68            return None;
69        }
70        
71        if self.iter_error.is_some() {
72            return Some(Err(self.iter_error.as_ref().unwrap().clone()));
73        }
74
75        let _next0 = self.iter0.next();
76        let _next1 = self.iter1.next();
77        match (&_next0, &_next1) {
78            (Some(v0), Some(v1)) => {
79                match (v0, v1) {
80                    (Ok(v0_t), Ok(v1_t)) => {
81                        let j = (self.pred)(v0_t, v1_t);
82                        if j.is_err() {
83                            self.iter_error = Some(j.as_ref().err().unwrap().clone());
84                            self.iter_finished = true;
85                        }
86                        return Some(j);
87                    }, 
88                    _ => {
89                        if v0.is_err() {
90                            self.iter_error = Some(error::any_error(v0.as_ref().err().unwrap().kind(), 
91                            "[map.v0] ".to_string()+v0.as_ref().err().unwrap().message().unwrap()));
92
93                            self.iter_finished = true;
94                            return Some(Err(self.iter_error.as_ref().unwrap().clone()));
95                        } else {
96                            self.iter_error = Some(error::any_error(v1.as_ref().err().unwrap().kind(), 
97                            "[map.v1] ".to_string()+v1.as_ref().err().unwrap().message().unwrap()));
98
99                            self.iter_finished = true;
100                            return Some(Err(self.iter_error.as_ref().unwrap().clone()));
101                        }
102                    }
103                }
104            },
105            _ => {
106                self.iter_finished = true;
107                return None;
108            },
109        }
110    }
111}
112
113pub fn map2<T0: 'static, T1: 'static, J: 'static>(
114    iter0: Box<dyn Iterator<Item = Result<T0,Error>>>, 
115    iter1: Box<dyn Iterator<Item = Result<T1,Error>>>,
116    pred: fn(&T0,&T1)->Result<J,Error>) -> Box<dyn Iterator<Item = Result<J,Error>>> 
117{
118    return Box::new(Map2 {
119        iter0,
120        iter1,
121        pred: pred,
122        iter_finished: false,
123        iter_error: None
124    });
125}
126
127
128#[cfg(test)]
129mod tests {
130    use crate::{error, utils::{extract_value_from_result_vec, generate_okok_iterator, generate_okokerr_iterator}};
131
132    use super::*;
133
134    #[test]
135    fn test1() {
136        let v = generate_okok_iterator(vec![1,2,3]);
137        let ret = map(v, |x| {Ok(x==3)});
138        let ret = extract_value_from_result_vec(ret.collect::<Vec<_>>());
139        assert!(ret.1.is_none());
140        assert_eq!(vec![false,false,true], ret.0);
141    }
142
143    #[test]
144    fn test1_error() {
145        let v = generate_okokerr_iterator(vec![1,2,3], error::overflow_error("for test".to_string()));
146        let ret = map(v, |x| {Ok(x==3)});
147        let ret = extract_value_from_result_vec(ret.collect::<Vec<_>>());
148        assert!(ret.1.is_some());
149        assert_eq!(vec![false,false,true], ret.0);
150    }
151
152    #[test]
153    fn test2() {
154        let v0 = generate_okok_iterator(vec![1,2,3]);
155        let v1 = generate_okok_iterator(vec![2,3,4]);
156        let ret = map2(v0, v1, |x,y| {Ok(x*y)});
157        let ret = extract_value_from_result_vec(ret.collect::<Vec<_>>());
158        assert!(ret.1.is_none());
159        assert_eq!(vec![2,6,12], ret.0);
160    }
161
162    #[test]
163    fn test2_result() {
164        let v0 = generate_okok_iterator(vec![1,2,i32::MAX]);
165        let v1 = generate_okok_iterator(vec![2,3,4]);
166        let mut ret = map2(
167            v0, 
168            v1, 
169            |x,y| {
170                let ret = x.overflowing_mul(*y);
171                if ret.1 {
172                    return Err(error::any_error(error::Kind::OverflowError, "multiple overflow.".to_string()));
173                } else {
174                    return Ok(ret.0);
175                }
176            }
177        );
178        assert_eq!(Ok(2), ret.next().unwrap());
179        assert_eq!(Ok(6), ret.next().unwrap());
180        assert_eq!(error::Kind::OverflowError, ret.next().unwrap().err().unwrap().kind());
181        assert_eq!(None, ret.next());
182    }
183}
184