Henry Bigelow
Henry Bigelow

Reputation: 323

How do I implement From to convert one Result type to another?

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:

How might I achieve this?

Upvotes: 1

Views: 966

Answers (1)

E_net4
E_net4

Reputation: 29972

One does not implement conversions between two Result types. Such a conversion is not needed for two reasons:

  1. 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);
    
  2. 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

Related Questions