resiter/
flat_map.rs
1pub trait FlatMap<O, E>: Sized {
9 fn flat_map_ok<U, F, O2>(self, _: F) -> FlatMapOk<Self, U, F>
21 where
22 F: FnMut(O) -> U,
23 U: IntoIterator<Item = O2>;
24
25 fn flat_map_err<U, F, E2>(self, _: F) -> FlatMapErr<Self, U, F>
41 where
42 F: FnMut(E) -> U,
43 U: IntoIterator<Item = E2>;
44}
45
46impl<I, O, E> FlatMap<O, E> for I
47where
48 I: Iterator<Item = Result<O, E>> + Sized,
49{
50 #[inline]
51 fn flat_map_ok<U, F, O2>(self, f: F) -> FlatMapOk<Self, U, F>
52 where
53 F: FnMut(O) -> U,
54 U: IntoIterator<Item = O2>,
55 {
56 FlatMapOk {
57 frontiter: None,
58 iter: self,
59 f,
60 }
61 }
62
63 #[inline]
64 fn flat_map_err<U, F, E2>(self, f: F) -> FlatMapErr<Self, U, F>
65 where
66 F: FnMut(E) -> U,
67 U: IntoIterator<Item = E2>,
68 {
69 FlatMapErr {
70 frontiter: None,
71 iter: self,
72 f,
73 }
74 }
75}
76
77#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
78pub struct FlatMapOk<I, U, F>
79where
80 U: IntoIterator,
81{
82 frontiter: Option<<U as IntoIterator>::IntoIter>,
83 iter: I,
84 f: F,
85}
86
87impl<I, O, E, F, O2, U> Iterator for FlatMapOk<I, U, F>
88where
89 I: Iterator<Item = Result<O, E>>,
90 F: FnMut(O) -> U,
91 U: IntoIterator<Item = O2>,
92{
93 type Item = Result<O2, E>;
94
95 fn next(&mut self) -> Option<Self::Item> {
96 loop {
97 if let Some(ref mut inner) = self.frontiter {
98 if let elt @ Some(_) = inner.next() {
99 return elt.map(Ok);
100 }
101 }
102 match self.iter.next() {
103 None => return None,
104 Some(Ok(x)) => {
105 self.frontiter = Some((self.f)(x).into_iter());
106 }
107 Some(Err(e)) => return Some(Err(e)),
108 }
109 }
110 }
111
112 #[inline]
113 fn size_hint(&self) -> (usize, Option<usize>) {
116 self.iter.size_hint()
117 }
118}
119
120#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
121pub struct FlatMapErr<I, U: IntoIterator, F> {
122 frontiter: Option<<U as IntoIterator>::IntoIter>,
123 iter: I,
124 f: F,
125}
126
127impl<I, O, E, F, E2, U> Iterator for FlatMapErr<I, U, F>
128where
129 I: Iterator<Item = Result<O, E>>,
130 F: FnMut(E) -> U,
131 U: IntoIterator<Item = E2>,
132{
133 type Item = Result<O, E2>;
134
135 fn next(&mut self) -> Option<Self::Item> {
136 loop {
137 if let Some(ref mut inner) = self.frontiter {
138 if let elt @ Some(_) = inner.next() {
139 return elt.map(Err);
140 }
141 }
142 match self.iter.next() {
143 None => return None,
144 Some(Err(e)) => {
145 self.frontiter = Some((self.f)(e).into_iter());
146 }
147 Some(Ok(o)) => return Some(Ok(o)),
148 }
149 }
150 }
151
152 #[inline]
153 fn size_hint(&self) -> (usize, Option<usize>) {
154 self.iter.size_hint()
155 }
156}