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}