iter_flow/lib.rs
1#![no_std]
2
3//! Extra iterator methods.
4//!
5//! To extend [`Iterator`] with methods in this crate, import the [`Iterflow`] trait:
6//!
7//! ```
8//! use iter_flow::Iterflow;
9//! ```
10//!
11//! Now, new methods like [`and_then`](Iterflow::and_then) are available on all Result's iterators:
12//!
13//! ```
14//! # use iter_flow::Iterflow;
15//! let it = (0..4)
16//! .map(|n| if n == 0 { Err("invalid!") } else { Ok(n - 1) })
17//! .and_then(|n| if n > 0 { Ok(n - 1) } else { Err("illegal!") })
18//! .map_ok(|n| (n + 1) * 2)
19//! .flat_map_ok(|n| (0..n));
20//!
21//! iter_flow::assert_equal(
22//! it,
23//! vec![
24//! Err("invalid!"),
25//! Err("illegal!"),
26//! Ok(0),
27//! Ok(1),
28//! Ok(0),
29//! Ok(1),
30//! Ok(2),
31//! Ok(3),
32//! ],
33//! );
34//! ```
35
36#[cfg(feature = "use_alloc")]
37extern crate alloc;
38
39#[cfg(feature = "use_alloc")]
40use alloc::vec::Vec;
41use core::fmt;
42
43/// The concrete iterator types.
44pub mod structs {
45 pub use crate::{
46 and_then::{AndThen, AndThenBorrow},
47 flatten::FlattenOk,
48 map_err::MapErr,
49 map_ok::{MapOk, MapOkBorrow},
50 };
51}
52
53mod and_then;
54mod flatten;
55mod map_err;
56mod map_ok;
57
58/// An [`Iterator`] blanket implementation that provides extra adaptors and
59/// methods.
60pub trait Iterflow: Iterator {
61 /// Return an iterator adaptor that applies the provided closure to every `Result::Err` value. `Result::Ok` values
62 /// are unchanged.
63 ///
64 /// ```
65 /// use iter_flow::Iterflow;
66 ///
67 /// let input = vec![Ok(41), Err(false), Err(true)];
68 /// let it = input.into_iter().map_err(|b| !b);
69 /// iter_flow::assert_equal(it, vec![Ok(41), Err(true), Err(false)]);
70 /// ```
71 fn map_err<F, T, E, R>(self, op: F) -> map_err::MapErr<Self, F>
72 where
73 Self: Iterator<Item = Result<T, E>> + Sized,
74 F: FnMut(E) -> R,
75 {
76 map_err::map_err(self, op)
77 }
78
79 /// Return an iterator adaptor that applies the provided closure to every `Result::Ok` value. `Result::Err` values
80 /// are unchanged.
81 ///
82 /// ```
83 /// use iter_flow::Iterflow;
84 ///
85 /// let input = vec![Ok(41), Err(false), Ok(11)];
86 /// let it = input.into_iter().map_ok(|i| i + 1);
87 /// iter_flow::assert_equal(it, vec![Ok(42), Err(false), Ok(12)]);
88 /// ```
89 fn map_ok<F, T, U, E>(self, op: F) -> map_ok::MapOk<Self, F>
90 where
91 Self: Iterator<Item = Result<T, E>> + Sized,
92 F: FnMut(T) -> U,
93 {
94 map_ok::map_ok(self, op)
95 }
96
97 /// Return an iterator adaptor that applies the provided closure to every `Result::Ok` value. `Result::Err` values
98 /// are unchanged.
99 ///
100 /// ```
101 /// use iter_flow::Iterflow;
102 ///
103 /// let input = vec![Ok(41), Err(false), Ok(11)];
104 /// let it = input.into_iter().map_ok_borrow(|i: &i32| i + 1);
105 /// iter_flow::assert_equal(it, vec![Ok(42), Err(false), Ok(12)]);
106 /// ```
107 fn map_ok_borrow<F, T, U, E>(self, op: F) -> map_ok::MapOkBorrow<Self, F>
108 where
109 Self: Iterator<Item = Result<T, E>> + Sized,
110 F: FnMut(&T) -> U,
111 {
112 map_ok::map_ok_borrow(self, op)
113 }
114
115 /// Return an iterator adaptor that applies the provided fallible closure to every `Result::Ok` value. `Result::Err`
116 /// values are unchanged.
117 ///
118 /// ```
119 /// use iter_flow::Iterflow;
120 ///
121 /// let input = vec![Ok(0), Err(false), Ok(11)];
122 /// let it = input
123 /// .into_iter()
124 /// .and_then(|i| if i == 0 { Err(false) } else { Ok(i - 1) });
125 /// iter_flow::assert_equal(it, vec![Err(false), Err(false), Ok(10)]);
126 /// ```
127 fn and_then<F, T, U, E, R>(self, op: F) -> and_then::AndThen<Self, F>
128 where
129 Self: Iterator<Item = Result<T, E>> + Sized,
130 F: FnMut(T) -> Result<U, R>,
131 E: From<R>,
132 {
133 and_then::and_then(self, op)
134 }
135
136 /// Return an iterator adaptor that applies the provided fallible closure to every `Result::Ok` value. `Result::Err`
137 /// values are unchanged.
138 ///
139 /// ```
140 /// use iter_flow::Iterflow;
141 ///
142 /// let input = vec![Ok(0), Err(false), Ok(11)];
143 /// let it = input
144 /// .into_iter()
145 /// .and_then_borrow(|i: &i32| if i == &0 { Err(false) } else { Ok(i - 1) });
146 /// iter_flow::assert_equal(it, vec![Err(false), Err(false), Ok(10)]);
147 /// ```
148 fn and_then_borrow<F, T, U, E, R>(self, op: F) -> and_then::AndThenBorrow<Self, F>
149 where
150 Self: Iterator<Item = Result<T, E>> + Sized,
151 F: FnMut(&T) -> Result<U, R>,
152 E: From<R>,
153 {
154 and_then::and_then_borrow(self, op)
155 }
156
157 /// Return an iterator adaptor that applies the provided closure to every `Result::Ok` value and then flattens it.
158 /// `Result::Err` values are unchanged.
159 ///
160 /// ```
161 /// use iter_flow::Iterflow;
162 ///
163 /// let input = vec![Ok(41), Err(false), Ok(11)];
164 /// let it = input.into_iter().flat_map_ok(|i| (i..=(i + 1)));
165 /// iter_flow::assert_equal(it, vec![Ok(41), Ok(42), Err(false), Ok(11), Ok(12)]);
166 /// ```
167 fn flat_map_ok<F, T, U, E>(self, op: F) -> flatten::FlattenOk<map_ok::MapOk<Self, F>, U, E>
168 where
169 Self: Iterator<Item = Result<T, E>> + Sized,
170 F: FnMut(T) -> U,
171 U: IntoIterator,
172 {
173 flatten::flat_map_ok(self, op)
174 }
175
176 /// Return an iterator adaptor that applies the provided closure to every `Result::Ok` value and then flattens it.
177 /// `Result::Err` values are unchanged.
178 ///
179 /// ```
180 /// use iter_flow::Iterflow;
181 ///
182 /// let input = vec![Ok(41), Err(false), Ok(11)];
183 /// let it = input
184 /// .into_iter()
185 /// .flat_map_ok_borrow(|i: &i32| (*i..=(*i + 1)));
186 /// iter_flow::assert_equal(it, vec![Ok(41), Ok(42), Err(false), Ok(11), Ok(12)]);
187 /// ```
188 fn flat_map_ok_borrow<F, T, U, E>(self, op: F) -> flatten::FlattenOk<map_ok::MapOkBorrow<Self, F>, U, E>
189 where
190 Self: Iterator<Item = Result<T, E>> + Sized,
191 F: FnMut(&T) -> U,
192 U: IntoIterator,
193 {
194 flatten::flat_map_ok_borrow(self, op)
195 }
196
197 /// Return an iterator adaptor that applies the provided fallible closure to every `Result::Ok` value and then
198 /// flattens it. `Result::Err` values are unchanged.
199 ///
200 /// ```
201 /// use iter_flow::Iterflow;
202 ///
203 /// let input = vec![Ok(0), Err(false), Ok(11)];
204 /// let it = input.into_iter().and_then_flat(|i| {
205 /// if i == 0 {
206 /// Err(false)
207 /// } else {
208 /// Ok(((i - 1)..=i))
209 /// }
210 /// });
211 /// iter_flow::assert_equal(it, vec![Err(false), Err(false), Ok(10), Ok(11)]);
212 /// ```
213 fn and_then_flat<F, T, U, E, R>(self, op: F) -> flatten::FlattenOk<and_then::AndThen<Self, F>, U, E>
214 where
215 Self: Iterator<Item = Result<T, E>> + Sized,
216 F: FnMut(T) -> Result<U, R>,
217 E: From<R>,
218 U: IntoIterator,
219 {
220 flatten::and_then_flat(self, op)
221 }
222
223 /// Return an iterator adaptor that applies the provided fallible closure to every `Result::Ok` value and then
224 /// flattens it. `Result::Err` values are unchanged.
225 ///
226 /// ```
227 /// use iter_flow::Iterflow;
228 ///
229 /// let input = vec![Ok(0), Err(false), Ok(11)];
230 /// let it = input.into_iter().and_then_flat_borrow(|i: &i32| {
231 /// if i == &0 {
232 /// Err(false)
233 /// } else {
234 /// Ok(((*i - 1)..=*i))
235 /// }
236 /// });
237 /// iter_flow::assert_equal(it, vec![Err(false), Err(false), Ok(10), Ok(11)]);
238 /// ```
239 fn and_then_flat_borrow<F, T, U, E, R>(self, op: F) -> flatten::FlattenOk<and_then::AndThenBorrow<Self, F>, U, E>
240 where
241 Self: Iterator<Item = Result<T, E>> + Sized,
242 F: FnMut(&T) -> Result<U, R>,
243 E: From<R>,
244 U: IntoIterator,
245 {
246 flatten::and_then_flat_borrow(self, op)
247 }
248
249 /// `.finish()` is simply a type specialization of [`Iterator::collect`],
250 /// for convenience.
251 fn finish<T, U, E>(self) -> Result<U, E>
252 where
253 Self: Iterator<Item = Result<T, E>> + Sized,
254 Result<U, E>: FromIterator<Result<T, E>>,
255 {
256 self.collect()
257 }
258
259 /// `.finish_vec()` is simply a type specialization of [`Iterator::collect`],
260 /// for convenience.
261 #[cfg(feature = "use_alloc")]
262 fn finish_vec<T, E>(self) -> Result<Vec<T>, E>
263 where
264 Self: Iterator<Item = Result<T, E>> + Sized,
265 {
266 self.collect()
267 }
268}
269
270impl<T: ?Sized> Iterflow for T where T: Iterator {}
271
272/// Assert that two iterables produce equal sequences, with the same
273/// semantics as [`equal(a, b)`](equal).
274///
275/// **Panics** on assertion failure with a message that shows the
276/// two iteration elements.
277///
278/// ```ignore
279/// assert_equal("exceed".split('c'), "excess".split('c'));
280/// // ^PANIC: panicked at 'Failed assertion Some("eed") == Some("ess") for iteration 1',
281/// ```
282pub fn assert_equal<I, J>(a: I, b: J)
283where
284 I: IntoIterator,
285 J: IntoIterator,
286 I::Item: fmt::Debug + PartialEq<J::Item>,
287 J::Item: fmt::Debug,
288{
289 let mut ia = a.into_iter();
290 let mut ib = b.into_iter();
291 let mut i = 0;
292 loop {
293 match (ia.next(), ib.next()) {
294 (None, None) => return,
295 (a, b) => {
296 let equal = match (&a, &b) {
297 (&Some(ref a), &Some(ref b)) => a == b,
298 _ => false,
299 };
300 assert!(
301 equal,
302 "Failed assertion {a:?} == {b:?} for iteration {i}",
303 i = i,
304 a = a,
305 b = b
306 );
307 i += 1;
308 }
309 }
310 }
311}