Reputation: 323
Is it possible to have a generic conversion of Result<T, ErrorType1>
to Result<T, ErrorType2>
, if ErrorType2::From(ErrorType1)
is already implemented? It seems like it should be possible.
This is my first attempt, but it doesn't compile.
impl<T> From<Result<T, LocalErrorType>> for Result<T, ForeignErrorType> {
fn from<T>(res: Result<T, LocalErrorType>) -> Self {
match sr {
Ok(o) => Ok(o),
Err(se) => Err(se.into())
}
}
}
because:
From
is a foreign trait
Result<T, LocalErrorType>
is a foreign type, despite LocalErrorType
being a local type
Result<T, ForeignErrorType>
is also a foreign type
How might I achieve this?
Upvotes: 1
Views: 966
Reputation: 29972
One does not implement conversions between two Result
types. Such a conversion is not needed for two reasons:
It is common and idiomatic to implement conversions between error types instead, from a specific type to a more generic error type. If none of the two types are more generic than the other one, one can create a new type that is the sum of both (i.e. an enum where each variant contains a distinct error type). With that, converting the result is as simple as using map_err
:
let res: Result<_, LocalErrorType> = do_something();
let res: Result<_, GenericErrorType> = res.map_err(From::from);
You might not need to call map_err
either, because the ?
operator (or the try!
macro before 1.13) already converts the error type using a similar procedure underneath.
fn do_something() -> Result<Foo, LocalErrorType> { unimplemented!() }
fn foo() -> Result<(), GenericErrorType> {
let stuff = do_something()?;
Ok(())
}
See also:
Upvotes: 2