How do I wrap multiple generic error types around a custom Error enum in Rust. Its pretty straightforward, I just want this to work.
enum Error<SPIE, PINE> {
SpiError(SPIE),
PinError(PINE),
// other custom errors
}
impl<SPIE,PINE> From<SPIE> for Error<SPIE,PINE> {
fn from(value: SPIE) -> Self {
Self::SpiError(value)
}
}
impl<SPIE,PINE> From<PINE> for Error<SPIE,PINE> {
fn from(value: PINE) -> Self {
Self::PinError(value)
}
}
Instead the compiler complains that:
conflicting implementations of trait `From<_>` for type `Error<_, _>`
which I understand, but perhaps I can distinguish the two types somehow...
This cannot work, because there is no way to constrain SPIE
and PINE
to be different types. If you try to convert a Foo
into an Error<Foo, Foo>
, which From
implementation should it use?
I'm not really sure there is a better approach than just constructing the enum variant directly. If your goal is to be able to use ?
in a function then you can just precede that with a call to map_err
like .map_err(Error::SpiError)?
to wrap the error in the SpiError
variant.
Two points that might make this even more ergonomic:
SpiError
is redundant when you're already in a type with an Error
suffix -- why not enum Error<SPIE, PINE> { Spi(SPIE), Pin(PINE) }
?use Error::*;
to import the variants directly.Combining both of these, the previous map_err
incantation can be shortened to .map_err(Spi)?
. It's not automatic, but it's not a whole lot of boilerplate either -- I use exactly this approach all the time.