Description
(This is a re-post of rust-lang/rust#38282, just in the correct place.) Using Option::map
together with the ?
operator is a pain. If you are mapping over an optional type, you can't use ?
inside the closure to signal error. This means that it's often impractical to map functions that return Result
s over optional types. Here's a way to alleviate that:
item.explanation = item.explanation
.and_then(|s| sanitize_links(&s).ok() ); // FIXME silently ignores errors
...but as noted in the comment, in the cases where the error matters, this is bad, and needs to be refactored into a match
statement.
It would help the ergonomics, if Option<T>
had a method – let's call it EDIT: a better name was suggested by @killercup: fallible_map
try_map
– like this:
try_map(self, FnOnce(T) → Result<U, E>) → Result<Option<U>, E>
What it would do, it would map the function over T
, but wrap an Ok
result into Option
and return that Option
wrapped into a Result
. This would allow mapping fallible functions over Option
s:
item.explanation = item.explanation
.try_map(|s| sanitize_links(&s))?;
...which, combined with ?
, allows neat, fluid APIs while handling errors properly.
Does adding this kind of an API to Option
need an RFC?
A simple implementation was demonstrated by @killercup here. As he mentioned, it could live in a 3rd party crate, but as a simple helper method that is in many ways similar to the already-existing Option::map
, Option::and_then
and others, helping with massaging the types in the right shape, I could easily imagine it being part of the standard API.
Note that alternative to this would be a method over Option<Result<T, E>>
that would "flip" the types to Result<Option<T>, E>
.