84. Result::flatten — Unwrap Nested Results in One Call
You have a Result<Result<T, E>, E> and just want the inner Result<T, E>. Before Rust 1.89, that meant a clunky and_then(|r| r). Now there’s Result::flatten.
The problem: nested Results
Nested Results crop up naturally — call a function that returns Result, then map over the success with another fallible operation:
| |
You end up with Ok(Ok(8080)) when you really want Ok(8080).
The old workaround
The standard trick was and_then with an identity closure:
| |
It works, but .and_then(|r| r) is a puzzler if you haven’t seen the pattern before.
The fix: flatten
Stabilized in Rust 1.89, Result::flatten does exactly what you’d expect:
| |
If the outer is Err, you get that Err. If the outer is Ok(Err(e)), you get Err(e). Only Ok(Ok(v)) becomes Ok(v).
Error propagation still works
Both layers must share the same error type. The flattening preserves whichever error came first:
| |
When to use flatten vs and_then
If you’re writing .map(f).flatten(), you probably want .and_then(f) — it’s the same thing, one call shorter. flatten shines when you already have a nested Result and just need to collapse it — say, from a generic API, a deserialized value, or a collection of results mapped over a fallible function.