Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I succinctly combine many `Result`s of different types?

Tags:

rust

Currently I use this pattern:

let a: Result<A, ParseError> = parseA();
let b: Result<B, ParseError> = parseB();
let c: Result<C, ParseError> = parseC();
a.and_then(|a| b.map(|b| (a, b))).and_then(|(a,b)| c.map(|c| {
  // finally the crux of what I want to do
  a.foo(b).bar(c)
}))

Is there a more succinct way to define a, b & c, such as Scala's for-expression?

like image 588
Synesso Avatar asked Jan 31 '17 06:01

Synesso


1 Answers

I usually wrap everything in layers instead of chaining through tuples:

let result = a.and_then(|a| {
    b.and_then(|b| {
        c.map(|c| {
            a.foo(b).bar(c)
        })
    })
});

Or, in recent Rust versions, you can make elaborate use of the ? operator:

let result = a.and_then(|a| {
    a.foo(b?).bar(c?)
});

Closures allow you to do this nicely and safely.

Of course this does not work if you want to store an intermediate Result in a variable.

like image 186
oli_obk Avatar answered Nov 16 '22 03:11

oli_obk