rustrust-result

In Rust, what's the most idiomatic way to convert a result to another result given the Error type is convertible


Let's say I call a function that returns me Result<Foo, Error1> and want to return Result<Foo, Error2>. Error2 implements From<Error1>.

The two options I have in mind are

fn f1() -> Result<Foo, Error2> {
  f2().map_err(|e| e.into())
}

or

fn f1() -> Result<Foo, Error2> {
  Ok(f2()?)
}

Is there a third, more idiomatic option? If not, which one should be preferred of the two?

I was expecting f2.into() to work out of the box, but it only works if From<Result<Foo, Error1>> is implemented for Result<Foo, Error2>.


Solution

  • A third option is to use Into::into directly in your call to map_err, like so:

    fn f1() -> Result<Foo, Error2> {
      f2().map_err(Into::into)
    }
    

    This is preferred over using a closure. Clippy actually has a lint for this: redundant_closure.

    This option is the most explicit in what it is doing. To an outside reader, there is no question how the conversion is happening. Contrastingly, while Ok(f2()?) works, the conversion is implicit and it is not immediately obvious how it is happening.