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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::error::Error;

use super::*;

impl<F, I> ExtraInto<Option<I>> for Option<F>
where
    F: Into<I>,
{
    fn into_extra(self) -> Option<I> {
        self.map(Into::into)
    }
}

/// Mapper for [Option]
pub fn option<F, I>(from: Option<F>) -> Option<I>
where
    F: Into<I>,
{
    from.map(Into::into)
}

/// Mapper for [Option]
pub fn option_extra<F, I>(from: Option<F>) -> Option<I>
where
    F: ExtraInto<I>,
{
    from.map(ExtraInto::into_extra)
}

/// Mapper to wrap into [Some]
pub fn add_option<F, I>(from: F) -> Option<I>
where
    F: Into<I>,
{
    Some(from.into())
}

/// Mapper to wrap into [Some]
pub fn add_option_extra<F, I>(from: F) -> Option<I>
where
    F: ExtraInto<I>,
{
    Some(from.into_extra())
}

impl<F, I> TryExtraInto<Option<I>> for Option<F>
where
    F: TryInto<I>,
{
    type Error = F::Error;

    fn try_into_extra(self) -> Result<Option<I>, Self::Error> {
        self.map(TryInto::try_into).transpose()
    }
}

/// Mapper for [Option]
pub fn try_option<F, I>(from: Option<F>) -> Result<Option<I>, <F as TryInto<I>>::Error>
where
    F: TryInto<I>,
{
    from.map(TryInto::try_into).transpose()
}

/// Mapper for [Option]
pub fn try_option_extra<F, I>(from: Option<F>) -> Result<Option<I>, <F as TryExtraInto<I>>::Error>
where
    F: TryExtraInto<I>,
{
    from.map(TryExtraInto::try_into_extra).transpose()
}

/// Mapper to wrap into [Some]
pub fn try_add_option<F, I>(from: F) -> Result<Option<I>, <F as TryInto<I>>::Error>
where
    F: TryInto<I>,
{
    Ok(Some(from.try_into()?))
}

/// Mapper to wrap into [Some]
pub fn try_add_option_extra<F, I>(from: F) -> Result<Option<I>, <F as TryExtraInto<I>>::Error>
where
    F: TryExtraInto<I>,
{
    Ok(Some(from.try_into_extra()?))
}

/// Mapper to unwrap an [Option]
pub fn try_remove_option<F, I>(from: Option<F>) -> Result<I, anyhow::Error>
where
    F: TryInto<I>,
    <F as TryInto<I>>::Error: Error + Send + Sync + 'static,
{
    match from {
        Some(f) => Ok(f.try_into()?),
        None => Err(anyhow::anyhow!("The value was required but not present")),
    }
}

/// Mapper to unwrap an [Option]
pub fn try_remove_option_extra<F, I>(from: Option<F>) -> Result<I, anyhow::Error>
where
    F: TryExtraInto<I>,
    <F as TryExtraInto<I>>::Error: Error + Send + Sync + 'static,
{
    match from {
        Some(f) => Ok(f.try_into_extra()?),
        None => Err(anyhow::anyhow!("The value was required but not present")),
    }
}