Iter Ator
Iter Ator

Reputation: 9289

How to wrap Result error in Some when using ? operator?

I have a function, that returns Option<Result<X, String>> and it calls some functions that return Result<Y, String>. How is it possible to use the ? operator in a way, that it wraps the error in a Some?

fn other_func() -> Result<Y, String> {
    // ...
}

fn my_func() -> Option<Result<X, String>> {
    // ...
    let value = other_func()?;
    // ...
}

I have two problems:

I am able to solve it with combining match and return, but I would like to use ? if it is possible somehow. This is my current solution:

let value = match other_func() {
    Ok(value) => value,
    Err(msg) => return Some(Err(msg))
};

Upvotes: 1

Views: 1126

Answers (2)

user4815162342
user4815162342

Reputation: 154916

You can use a helper function or closure that returns Result<Option<X>, String>, and then call transpose(). For example:

fn my_func() -> Option<Result<X, String>> {
    (|| -> Result<Option<X>, String> {
        // ...
        let _value = other_func()?;
        // ...
        Ok(None)
    })()
    .transpose()
}

If this use of closure is too obscure, you can simply define an inner fn helper() and call helper().transpose() (or define the helper outside my_func).

Upvotes: 0

Tyler Aldrich
Tyler Aldrich

Reputation: 416

This isn't possible using the ? operator, you would have to do what your current solution is.

Here is some info on what the ? operator does: https://doc.rust-lang.org/rust-by-example/std/result/question_mark.html - it is just syntactic sugar around

match <expr> {
  Ok(val) => val,
  Err(err) => {
    return Err(From::from(err))
  }
}

so the only way to wrap your Err in Some(err) is by manually matching as you've done.

Upvotes: 3

Related Questions