-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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 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 EDIT: a better name was suggested by @killercup: fallible_maptry_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>.