DEV Community

Daniel Imfeld
Daniel Imfeld

Posted on • Originally published at imfeld.dev on

Switching Result and Option in Rust with Transpose

When writing Rust code, it’s common to have an Option value that you want to map through some fallible operation. For example, you have an Option<String> and you want to parse it as an integer. You could do something like this:

fn parse_maybe_int(s: Option<String>) -> Option<Result<i32, ParseIntError>> {
    s.map(|s| s.parse::<i32>())
}
Enter fullscreen mode Exit fullscreen mode

But this gets awkward if you want to return an error when the parsing fails, but don’t want to unwrap the Option just yet. When I first started writing Rust I would use the match syntax to take care of it.

let input = Some("3".to_string());
let value = match parse_maybe_int(input) {
    Some(Ok(value)) => value,
    Some(Err(e)) => return Err(e),
    None => None,
};

Enter fullscreen mode Exit fullscreen mode

One of Rust’s best features is the ? operator, which allows you to unwrap a Result and return if it’s an error. So having to write this match every time gets old quick.

Fortunately, there’s a method in the standard library that addresses this exact problem. When you have anOption<Result<T, _>> or a Result<Option<T>, _> you can use the transpose method to swap the Result and Option.

let input = Some("3".to_string());
let value = parse_maybe_int(input).transpose()?;
Enter fullscreen mode Exit fullscreen mode

And then from there, you can build the transpose straight into the method:

fn parse_maybe_int(s: Option<String>) -> Result<Option<i32>, ParseIntError> {
    s.map(|s| s.parse::<i32>()).transpose()
}

let input = Some("3".to_string());
let value = parse_maybe_int(input)?;
Enter fullscreen mode Exit fullscreen mode

Much better. I haven’t seen transpose mentioned much, but I’ve found it very useful, so I hope this helps someone.

Top comments (0)