resiter_dpc_tmp/
filter_map.rs1pub trait FilterMap<O, E>: Sized {
9 fn filter_map_ok<F, O2>(self, F) -> FilterMapOk<Self, F>
10 where
11 F: FnMut(O) -> Option<O2>;
12 fn filter_map_err<F, E2>(self, F) -> FilterMapErr<Self, F>
13 where
14 F: FnMut(E) -> Option<E2>;
15}
16
17impl<I, O, E> FilterMap<O, E> for I
18where
19 I: Iterator<Item = Result<O, E>> + Sized,
20{
21 fn filter_map_ok<F, O2>(self, f: F) -> FilterMapOk<Self, F>
22 where
23 F: FnMut(O) -> Option<O2>,
24 {
25 FilterMapOk { iter: self, f }
26 }
27 fn filter_map_err<F, E2>(self, f: F) -> FilterMapErr<Self, F>
28 where
29 F: FnMut(E) -> Option<E2>,
30 {
31 FilterMapErr { iter: self, f }
32 }
33}
34
35#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
36pub struct FilterMapOk<I, F> {
37 iter: I,
38 f: F,
39}
40
41impl<I, O, E, F, O2> Iterator for FilterMapOk<I, F>
42where
43 I: Iterator<Item = Result<O, E>>,
44 F: FnMut(O) -> Option<O2>,
45{
46 type Item = Result<O2, E>;
47
48 fn next(&mut self) -> Option<Self::Item> {
49 loop {
50 match self.iter.next() {
51 Some(Ok(x)) => {
52 if let Some(x) = (self.f)(x) {
53 return Some(Ok(x));
54 }
55 }
56 Some(Err(e)) => return Some(Err(e)),
57 None => return None,
58 }
59 }
60 }
61
62 #[inline]
63 fn size_hint(&self) -> (usize, Option<usize>) {
64 self.iter.size_hint()
65 }
66}
67
68#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
69pub struct FilterMapErr<I, F> {
70 iter: I,
71 f: F,
72}
73
74impl<I, O, E, F, E2> Iterator for FilterMapErr<I, F>
75where
76 I: Iterator<Item = Result<O, E>>,
77 F: FnMut(E) -> Option<E2>,
78{
79 type Item = Result<O, E2>;
80
81 fn next(&mut self) -> Option<Self::Item> {
82 loop {
83 match self.iter.next() {
84 Some(Ok(x)) => return Some(Ok(x)),
85 Some(Err(e)) => {
86 if let Some(e) = (self.f)(e) {
87 return Some(Err(e));
88 }
89 }
90 None => return None,
91 }
92 }
93 }
94 #[inline]
95 fn size_hint(&self) -> (usize, Option<usize>) {
96 self.iter.size_hint()
97 }
98}
99
100#[test]
101fn test_filter_map_ok() {
102 use std::str::FromStr;
103
104 let filter_mapped: Vec<_> = vec![
105 Ok("1"),
106 Err("2"),
107 Ok("a"),
108 Err("4"),
109 Ok("5"),
110 Err("b"),
111 Err("8"),
112 ].into_iter()
113 .filter_map_ok(|txt| usize::from_str(txt).ok())
114 .filter_map_err(|txt| usize::from_str(txt).ok().map(|i| i * 3))
115 .collect();
116
117 assert_eq!(filter_mapped[0], Ok(1));
118 assert_eq!(filter_mapped[1], Err(2 * 3));
119 assert_eq!(filter_mapped[2], Err(4 * 3));
120 assert_eq!(filter_mapped[3], Ok(5));
121 assert_eq!(filter_mapped[4], Err(8 * 3));
122}
123
124#[test]
125fn test_filter_map_ok_hint() {
126 use std::str::FromStr;
127
128 let hint = ["1", "2", "a", "4", "5"]
129 .into_iter()
130 .map(|txt| usize::from_str(txt))
131 .filter_map_ok(|i| Some(2 * i))
132 .size_hint();
133
134 assert_eq!(hint, (5, Some(5)));
135}
136
137#[test]
138fn test_filter_map_err_hint() {
139 use std::str::FromStr;
140
141 let hint = ["1", "2", "a", "4", "5"]
142 .into_iter()
143 .map(|txt| usize::from_str(txt))
144 .filter_map_err(|e| Some(format!("{:?}", e)))
145 .size_hint();
146
147 assert_eq!(hint, (5, Some(5)));
148}