resiter/
onok.rs

1//
2// This Source Code Form is subject to the terms of the Mozilla Public
3// License, v. 2.0. If a copy of the MPL was not distributed with this
4// file, You can obtain one at http://mozilla.org/MPL/2.0/.
5//
6
7#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
8pub struct OnOk<I, O, E, F>(I, F)
9where
10    I: Iterator<Item = Result<O, E>>,
11    F: FnMut(&O);
12
13/// Extension trait for `Iterator<Item = Result<T, E>>` to do something on `Ok(_)`
14pub trait OnOkDo<I, O, E, F>
15where
16    I: Iterator<Item = Result<O, E>>,
17    F: FnMut(&O),
18{
19    /// Perform a side effect on each Ok value
20    ///
21    /// ```
22    /// use resiter::onok::OnOkDo;
23    /// use std::str::FromStr;
24    ///
25    /// let mut oks = Vec::new();
26    /// let _: Vec<Result<usize, ::std::num::ParseIntError>> = ["1", "2", "a", "b", "5"]
27    ///     .iter()
28    ///     .map(|e| usize::from_str(e))
29    ///     .on_ok(|e| oks.push(e.to_owned()))
30    ///     .collect();
31    ///
32    /// assert_eq!(oks, vec![1, 2, 5]);
33    /// ```
34    fn on_ok(self, _: F) -> OnOk<I, O, E, F>;
35}
36
37impl<I, O, E, F> OnOkDo<I, O, E, F> for I
38where
39    I: Iterator<Item = Result<O, E>>,
40    F: FnMut(&O),
41{
42    #[inline]
43    fn on_ok(self, f: F) -> OnOk<I, O, E, F> {
44        OnOk(self, f)
45    }
46}
47
48impl<I, O, E, F> Iterator for OnOk<I, O, E, F>
49where
50    I: Iterator<Item = Result<O, E>>,
51    F: FnMut(&O),
52{
53    type Item = Result<O, E>;
54
55    fn next(&mut self) -> Option<Self::Item> {
56        self.0.next().map(|r| {
57            r.map(|o| {
58                (self.1)(&o);
59                o
60            })
61        })
62    }
63}