someval/
some3.rs

1#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2pub enum Some3<A, B, C> {
3    A(A),
4    B(B),
5    C(C),
6    AB(A, B),
7    AC(A, C),
8    BC(B, C),
9    ABC(A, B, C),
10}
11use Some3::*;
12
13impl<A, B, C> Some3<A, B, C> {
14    pub fn try_from_options(a: Option<A>, b: Option<B>, c: Option<C>) -> Option<Self> {
15        match (a, b, c) {
16            (None, None, None) => None,
17            (Some(a), None, None) => Some(A(a)),
18            (None, Some(b), None) => Some(B(b)),
19            (None, None, Some(c)) => Some(C(c)),
20            (Some(a), Some(b), None) => Some(AB(a, b)),
21            (Some(a), None, Some(c)) => Some(AC(a, c)),
22            (None, Some(b), Some(c)) => Some(BC(b, c)),
23            (Some(a), Some(b), Some(c)) => Some(ABC(a, b, c)),
24        }
25    }
26
27    pub fn as_ref(&self) -> Some3<&A, &B, &C> {
28        match self {
29            A(a) => A(a),
30            B(b) => B(b),
31            C(c) => C(c),
32            AB(a, b) => AB(a, b),
33            AC(a, c) => AC(a, c),
34            BC(b, c) => BC(b, c),
35            ABC(a, b, c) => ABC(a, b, c),
36        }
37    }
38
39    pub fn a(self) -> Option<A> {
40        let (opta, _, _) = self.into();
41        opta
42    }
43
44    pub fn b(self) -> Option<B> {
45        let (_, optb, _) = self.into();
46        optb
47    }
48
49    pub fn c(self) -> Option<C> {
50        let (_, _, optc) = self.into();
51        optc
52    }
53}
54
55impl<A, B, C> TryFrom<(Option<A>, Option<B>, Option<C>)> for Some3<A, B, C> {
56    type Error = &'static str;
57
58    fn try_from(
59        (opta, optb, optc): (Option<A>, Option<B>, Option<C>),
60    ) -> Result<Self, Self::Error> {
61        Self::try_from_options(opta, optb, optc).ok_or("no value of any accepted type present")
62    }
63}
64
65impl<A, B, C> From<(A, B, C)> for Some3<A, B, C> {
66    fn from((a, b, c): (A, B, C)) -> Self {
67        ABC(a, b, c)
68    }
69}
70
71impl<A, B, C> From<Some3<A, B, C>> for (Option<A>, Option<B>, Option<C>) {
72    fn from(sp: Some3<A, B, C>) -> (Option<A>, Option<B>, Option<C>) {
73        match sp {
74            A(a) => (Some(a), None, None),
75            B(b) => (None, Some(b), None),
76            C(c) => (None, None, Some(c)),
77            AB(a, b) => (Some(a), Some(b), None),
78            AC(a, c) => (Some(a), None, Some(c)),
79            BC(b, c) => (None, Some(b), Some(c)),
80            ABC(a, b, c) => (Some(a), Some(b), Some(c)),
81        }
82    }
83}