In some code I was looking through recently, I came across the following pattern:

match a.do_something() {
    Ok(b) => {
        match b.do_something_else() {
            Ok(_) => Ok(()),
            Err(err) => CustomError::from(err),
        }
    }
    Err(err) => CustomError::from(err),
}

It is very clear what that code is doing, and what all the possible paths are. However, there are ways of shortening this and reducing the level of indentation required. We could, for example, use try!(...) (or ...? in 1.13):

let mut b = try!(a.do_something());

try!(b.do_something_else());

Ok(())

However, this has certain drawbacks. This would fall apart if we wanted to do anything clever with the errors (e.g. write an error log before returning). I’m also not particularly fond of try! - it implicitly introduces a bunch of return calls into the code.

Instead, the pattern I’ve come to prefer is as follows:

a.do_something()
    .and_then(|b| b.do_something_else())
    .map(|_| ())
    .map_err(CustomError::from)

This has the advantage of conciseness, with each quantum of functionality on a separate line.

std::option::Option and std::result::Result are two very powerful elements of Rust, both with a number of very useful methods. I’d thoroughly recommend reading their docs - I’ve been referring to both quite a bit lately, and think it has helped the readability of the code I’ve written.