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
// It'd be convenient to demand TryFrom<u8, Error: core::fmt::Debug>, but RFC 2289 hasn't landed in
// stable yet
pub trait Code: Into<u8> + core::convert::TryFrom<u8> {}

impl Code for u8 {}

pub trait OptionNumber: Into<u16> + core::convert::TryFrom<u16> {}

impl OptionNumber for u16 {}

/// Experimental trait for conversion between option representation, with the goal to later avoid
/// the conversion step via u16 and specialize for T->T conversions.
pub trait FromOtherOption<O: OptionNumber> {
    type Error;

    fn convert_from_other(other: O) -> Result<Self, Self::Error>
    where
        Self: Sized;
}

impl<O: OptionNumber, T: OptionNumber> FromOtherOption<O> for T
{
    type Error = <Self as core::convert::TryFrom<u16>>::Error;

    /* default */ fn convert_from_other(other: O) -> Result<Self, Self::Error>
    where
        Self: Sized
    {
        let num: u16 = other.into();
        use core::convert::TryInto;
        num.try_into()
    }
}

/*

needs
#![feature(specialization)]
and the above default to be active

impl<T: OptionNumber> FromOtherOption<T> for T
{
//     type Error = <Self as core::convert::TryFrom<u16>>::Error; // lont term I'd like to have `!` here
//
    fn convert_from_other(other: T) -> Result<Self, Self::Error>
    where
        Self: Sized
    {
        Ok(other)
    }
}
*/