1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#[cfg(feature = "result")]
pub mod result;

/// Extensions for `Option<T>` where `T: Default`
pub trait OptionExtDefault<T> {
    /// If `self` is `Some(v)`, returns v, otherwise returns `Default::default()`
    fn or_default(self) -> T;
}

impl<T> OptionExtDefault<T> for Option<T> where
    T: Default,
{
    #[inline]
    fn or_default(self) -> T {
        self.unwrap_or_else(Default::default)
    }
}

#[cfg(feature = "result")]
impl<T, E> OptionExtDefault<T> for Result<T, E> where
    T: Default,
{
    #[inline]
    fn or_default(self) -> T {
        self.ok().or_default()
    }
}

pub trait TupleExtFlip<A, B>: Sized {
    fn flipped(self) -> (B, A);
}

impl<A, B> TupleExtFlip<A, B> for (A, B) {
    fn flipped(self) -> (B, A) {
        let (a, b) = self;
        (b, a)
    }
}

/// Extensions for Option<T> for dealing with tuples
pub trait OptionExtTup<T>: Sized {
    fn and_then_tup<F, Ret>(self, f: F) -> Option<(T, Ret)> where
        Ret: Sized,
        F: FnOnce(&T) -> Option<Ret>;
    fn and_then_tup_flipped<F, Ret>(self, f: F) -> Option<(Ret, T)> where
        Ret: Sized,
        F: FnOnce(&T) -> Option<Ret>
    {
        self.and_then_tup(f).map(TupleExtFlip::flipped)
    }
    fn and_tup<Ret>(self, v: Option<Ret>) -> Option<(T, Ret)> {
        self.and_then_tup(move |_| v)
    }
    fn and_tup_flipped<Ret>(self, v: Option<Ret>) -> Option<(Ret, T)> {
        self.and_tup(v).map(TupleExtFlip::flipped)
    }
}

impl<T: Sized> OptionExtTup<T> for Option<T> {
    fn and_then_tup<F, Ret>(self, f: F) -> Option<(T, Ret)> where
        Ret: Sized,
        F: FnOnce(&T) -> Option<Ret>,
    {
        self.and_then(move |v| f(&v).map(move |vv| (v, vv)))
    }
}