How do I unwrap an arbitrary number of nested Option types?

generics, rust

Solution

Instead of flattening out the nested option, as the other answer shows, I'd advocate that you never create an `Option<Option<T>>` that you need to flatten in the first place. In the majority of cases I've seen, it's because someone misuses `Option::map` when they should have used `Option::and_then`:

fn main() {
    let input = user_input();

    let a = input.map(add1);
    // a is Option<Option<i32>>

    let b = input.and_then(add1);
    // a is Option<i32>
}

fn user_input() -> Option<i32> {
    Some(10)
}

fn add1(a: i32) -> Option<i32> {
    Some(a + 1)
}

Remember that Rust is a statically typed language; you will always know the exact level of nesting.

See also:

- Flatten nested Results in Rust

Problem

I'm trying to write a trait that will allow me to "unwrap" multiple nested `Option<Option<...<T>>>>` to a single `Option<T>` to better work with an API I am using. I'm trying to create a generic solution, but I can't figure out how to make it work. This is one of my many attempts: ``` trait UnwrapOption<T> { fn unwrap_opt(self) -> Option<T>; } impl<T> UnwrapOption<T> for Option<T> { fn unwrap_opt(self) -> Option<T> { self } } impl<T> UnwrapOption<T> for Option<Option<T>> { fn unwrap_opt(self) -> Option<T> { match self { Some(e) => e.unwrap_opt(), None => None, } } } fn main() { let x = Some(Some(Some(1))); println!("{:?}", x.unwrap_opt()); } ``` ``` error[E0282]: type annotations needed --> src/main.rs:22:24 | 22 | println!("{:?}", x.unwrap_opt()); | --^^^^^^^^^^-- | | | | | cannot infer type for type parameter `T` declared on the trait `UnwrapOption` | this method call resolves to `Option<T>` ```

Original source

Related problems