Skip to main content

stefans_utils/
map_into.rs

1pub trait MapInto<T> {
2    fn map_into(self) -> T;
3}
4
5impl<A: Into<B>, B> MapInto<Option<B>> for Option<A> {
6    fn map_into(self) -> Option<B> {
7        self.map(A::into)
8    }
9}
10
11impl<OkA: Into<OkB>, ErrA: Into<ErrB>, OkB, ErrB> MapInto<Result<OkB, ErrB>> for Result<OkA, ErrA> {
12    fn map_into(self) -> Result<OkB, ErrB> {
13        match self {
14            Ok(a) => Ok(a.into()),
15            Err(err_a) => Err(err_a.into()),
16        }
17    }
18}
19
20#[cfg(test)]
21mod tests {
22    use super::*;
23
24    #[derive(Debug, PartialEq)]
25    struct A;
26    #[derive(Debug, PartialEq)]
27    struct B;
28    #[derive(Debug, PartialEq)]
29    struct C;
30    #[derive(Debug, PartialEq)]
31    struct D;
32
33    impl From<A> for B {
34        fn from(_: A) -> Self {
35            B
36        }
37    }
38
39    impl From<B> for A {
40        fn from(_: B) -> Self {
41            A
42        }
43    }
44
45    impl From<C> for D {
46        fn from(_: C) -> Self {
47            D
48        }
49    }
50
51    impl From<D> for C {
52        fn from(_: D) -> Self {
53            C
54        }
55    }
56
57    #[test]
58    fn map_options() {
59        fn check<
60            A: Into<B> + PartialEq + std::fmt::Debug,
61            B: Into<A> + PartialEq + std::fmt::Debug,
62        >(
63            a: Option<A>,
64            b: Option<B>,
65        ) {
66            assert_eq!(a.map_into(), b);
67        }
68
69        check(Option::<A>::Some(A), Option::<B>::Some(B));
70        check(Option::<A>::None, Option::<B>::None);
71    }
72
73    #[test]
74    fn map_results_into() {
75        fn check<
76            A: Into<B> + PartialEq + std::fmt::Debug,
77            B: Into<A> + PartialEq + std::fmt::Debug,
78            C: Into<D> + PartialEq + std::fmt::Debug,
79            D: Into<C> + PartialEq + std::fmt::Debug,
80        >(
81            a: Result<A, C>,
82            b: Result<B, D>,
83        ) {
84            assert_eq!(a.map_into(), b);
85        }
86
87        // AC/BD - No shared types
88        check(Result::<A, C>::Ok(A), Result::<B, D>::Ok(B));
89        check(Result::<B, D>::Ok(B), Result::<A, C>::Ok(A));
90        check(Result::<A, C>::Err(C), Result::<B, D>::Err(D));
91        check(Result::<B, D>::Err(D), Result::<A, C>::Err(C));
92
93        // AC/AD - Shared Ok type
94        check(Result::<A, C>::Ok(A), Result::<A, D>::Ok(A));
95        check(Result::<A, D>::Ok(A), Result::<A, C>::Ok(A));
96        check(Result::<A, C>::Err(C), Result::<A, D>::Err(D));
97        check(Result::<A, D>::Err(D), Result::<A, C>::Err(C));
98
99        // AC/BC - Shared Err type
100        check(Result::<A, C>::Ok(A), Result::<B, C>::Ok(B));
101        check(Result::<B, C>::Ok(B), Result::<A, C>::Ok(A));
102        check(Result::<A, C>::Err(C), Result::<B, C>::Err(C));
103        check(Result::<B, C>::Err(C), Result::<A, C>::Err(C));
104
105        // AC/AC - All types shared
106        check(Result::<A, A>::Ok(A), Result::<A, A>::Ok(A));
107        check(Result::<A, A>::Err(A), Result::<A, A>::Err(A));
108    }
109}