Skip to content

Fallible try_map on Option #1815

Open
Open
@golddranks

Description

@golddranks

(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>.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiRelevant to the library API team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions