(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 Results 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 fallible_map EDIT: a better name was suggested by @killercup: 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 Options:
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>.
(This is a re-post of rust-lang/rust#38282, just in the correct place.) Using
Option::maptogether 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 returnResults over optional types. Here's a way to alleviate that:...but as noted in the comment, in the cases where the error matters, this is bad, and needs to be refactored into a
matchstatement.It would help the ergonomics, if
Option<T>had a method – let's call itEDIT: a better name was suggested by @killercup:fallible_maptry_map– like this:What it would do, it would map the function over
T, but wrap anOkresult intoOptionand return thatOptionwrapped into aResult. This would allow mapping fallible functions overOptions:...which, combined with
?, allows neat, fluid APIs while handling errors properly.Does adding this kind of an API to
Optionneed 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_thenand 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 toResult<Option<T>, E>.