resiter_dpc_tmp/
map.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/// Extension trait for `Iterator<Item = Result<O, E>>` to selectively transform Oks and Errors.
8pub trait Map<O, E>: Sized {
9    fn map_ok<F, O2>(self, F) -> MapOk<Self, F>
10    where
11        F: FnMut(O) -> O2;
12    fn map_err<F, E2>(self, F) -> MapErr<Self, F>
13    where
14        F: FnMut(E) -> E2;
15}
16
17impl<I, O, E> Map<O, E> for I
18where
19    I: Iterator<Item = Result<O, E>> + Sized,
20{
21    fn map_ok<F, O2>(self, f: F) -> MapOk<Self, F>
22    where
23        F: FnMut(O) -> O2,
24    {
25        MapOk { iter: self, f }
26    }
27    fn map_err<F, E2>(self, f: F) -> MapErr<Self, F>
28    where
29        F: FnMut(E) -> E2,
30    {
31        MapErr { iter: self, f }
32    }
33}
34
35#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
36pub struct MapOk<I, F> {
37    iter: I,
38    f: F,
39}
40
41impl<I, O, E, F, O2> Iterator for MapOk<I, F>
42where
43    I: Iterator<Item = Result<O, E>>,
44    F: FnMut(O) -> O2,
45{
46    type Item = Result<O2, E>;
47
48    fn next(&mut self) -> Option<Self::Item> {
49        self.iter.next().map(|r| r.map(&mut self.f))
50    }
51
52    #[inline]
53    fn size_hint(&self) -> (usize, Option<usize>) {
54        self.iter.size_hint()
55    }
56}
57
58#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
59pub struct MapErr<I, F> {
60    iter: I,
61    f: F,
62}
63
64impl<I, O, E, F, E2> Iterator for MapErr<I, F>
65where
66    I: Iterator<Item = Result<O, E>>,
67    F: FnMut(E) -> E2,
68{
69    type Item = Result<O, E2>;
70
71    fn next(&mut self) -> Option<Self::Item> {
72        self.iter.next().map(|r| r.map_err(&mut self.f))
73    }
74
75    #[inline]
76    fn size_hint(&self) -> (usize, Option<usize>) {
77        self.iter.size_hint()
78    }
79}
80
81#[test]
82fn test_map_ok() {
83    use std::str::FromStr;
84
85    let mapped: Vec<_> = ["1", "2", "a", "4", "5"]
86        .into_iter()
87        .map(|txt| usize::from_str(txt))
88        .map_ok(|i| 2 * i)
89        .collect();
90
91    assert_eq!(mapped[0], Ok(2));
92    assert_eq!(mapped[1], Ok(4));
93    assert_eq!(mapped[3], Ok(8));
94    assert_eq!(mapped[4], Ok(10));
95}
96
97#[test]
98fn test_map_ok_hint() {
99    use std::str::FromStr;
100
101    let hint = ["1", "2", "a", "4", "5"]
102        .into_iter()
103        .map(|txt| usize::from_str(txt))
104        .map_ok(|i| 2 * i)
105        .size_hint();
106
107    assert_eq!(hint, (5, Some(5)));
108}
109
110#[test]
111fn test_map_err() {
112    use std::str::FromStr;
113
114    let mapped: Vec<_> = ["1", "2", "a", "4", "5"]
115        .into_iter()
116        .map(|txt| usize::from_str(txt))
117        .map_err(|e| format!("{:?}", e))
118        .collect();
119
120    assert_eq!(
121        mapped[2],
122        Err("ParseIntError { kind: InvalidDigit }".to_string())
123    );
124}
125
126#[test]
127fn test_map_err_hint() {
128    use std::str::FromStr;
129
130    let hint = ["1", "2", "a", "4", "5"]
131        .into_iter()
132        .map(|txt| usize::from_str(txt))
133        .map_err(|e| format!("{:?}", e))
134        .size_hint();
135
136    assert_eq!(hint, (5, Some(5)));
137}