I am attempting to use TryFrom
to convert types, except that I would like to use a generic error type. How can I extend TryFrom
to cope with an additional generic error parameter?
use core::convert::TryFrom;
enum MyError<E> {
UnexpectedValue,
SomeGeneric(E),
}
enum MyEnum {
Zero,
One,
Two,
}
impl TryFrom<u32> for MyEnum {
type Error = MyError<E>;
fn try_from(value: u32) -> Result<Self, Self::Error> {
match value {
0 => Ok(MyEnum::Zero),
1 => Ok(MyEnum::One),
2 => Ok(MyEnum::Two),
_ => Err(MyError::UnexpectedValue),
}
}
}
I wondered if I could extend TryFrom
into a new trait which incorporates a generic error parameter, but I'm not sure how to go about doing that.
The associated Error
type of TryFrom
is not generic and introducing a generic E
(i.e. impl<E> TryFrom<u32> for MyEnum
) would be unconstrained, so you cannot do this.
Likely your best route would be to create a distinct error type for your conversion with a From
implementation that can convert it to your desired error type. That way, a ?
might convert transparently or you'd use .map_err(MyError::<_>::from)
if it doesn't.
Demonstration:
struct UnexpectedMyEnumValue;
impl<E> From<UnexpectedMyEnumValue> for MyError<E> {
fn from(err: UnexpectedMyEnumValue) -> MyError<E> {
MyError::UnexpectedValue
}
}
impl TryFrom<u32> for MyEnum {
type Error = UnexpectedMyEnumValue;
fn try_from(value: u32) -> Result<Self, Self::Error> {
match value {
0 => Ok(MyEnum::Zero),
1 => Ok(MyEnum::One),
2 => Ok(MyEnum::Two),
_ => Err(UnexpectedMyEnumValue),
}
}
}
fn f() -> Result<(), MyError<()>> {
let _e = MyEnum::try_from(5)?; // converts to MyError automatically
Ok(())
}