Brian Campbell
Brian Campbell

Reputation: 332866

Equivalent of map_err that uses from_error automatically

Result has an map_err function that allows you to map Result<T, E> to a Result<T, F> by applying a function to the error value.

For types that implement FromError, the most natural function to apply would just be FromError::from_error, leading to something like the following:

foo()
  .map_err(FromError::from_error)
  .and_then(|val| {
      val.do_something().map_err(FromError::from_err)
  })

It seems that for this kind of use case, there should be a less cumbersome method defined on Result<T, E> where E: Error that calls FromError::from_error less verbosely, something like the following but with a better name:

foo()
  .wrap_err()
  .and_then(|val| {
      val.do_something().wrap_err()
  })

This would just be equivalent to .map_err(FromError::from_error), simply shorter and more convenient for when you're doing this kind of method chaining.

Is there something like this defined anywhere? I could not find it, though I'm not sure if I was looking in all of the right places in the documentation.

This question was inspired my my answer to this one, in which I described both FromError for use with try! but realized it didn't help with the method-chaining style being used there.

Upvotes: 4

Views: 2076

Answers (1)

Chris Morgan
Chris Morgan

Reputation: 90762

There is no such method at least at present. I believe that in practical situations try! is used somewhat more commonly than the method chaining approach (and it tends to yield nicer code in my opinion), so it’s not been such an important consideration.

Potentially more interesting as a design consideration would be changing and_then et al. to use FromError:

pub fn and_then<U, E2: FromError<E>, F: FnOnce(T) -> Result<U, E2>>
               (self, op: F) -> Result<U, E2> {
    match self {
        Ok(t) => op(t),
        Err(e) => Err(FromError::from_error(e)),
    }
}

… but I don’t believe this will happen, because they’re marked stable and it would be a just slightly backwards-incompatible change.

Upvotes: 4

Related Questions