Mapping an Option to a result

Hi,
I have an option coming back from serde_json untyped parsing as in:
json_value["field"].as_str() which returns an Option<&str>. I want to parse this slice to an enum type. The idiomatic way of implementing the parsing for a type from a &str is std::str::FromStr which has the type signature: fn from_str(s: &str) -> Result<Self, Self::Err>.
My goal is to return an Option<MyType> (I don't usually care about the error type).
Is there an elegant, idiomatic way to do this?
One options that comes to mind is: json_value["field"].as_str().ok_or("mising field").map(str::parse::<MyType>)
But this gives me a: Result<Result<MyType, SomeErr>, &str> which is inconvenient.

You can .unwrap() an Option<T> or Result<T> to get the inner value. But on encountering a None or an error it will panic. You can also use pattern matching to go from Result to Option or vice versa:

let result: Option<MyType> = match double_result {
    Ok(Ok(my_type)) => Some(my_type),
    Err(_) | Ok(Err(_)) => None,
}

The second branch is for completeness, but _ => None would be just as good.

A variant of that is:

json_value["field"].as_str().ok_or(MissingFieldError).and_then(str::parse::<MyType>)

Here MissingFieldError should be of the same type as the error from str::parse::<MyType>. Or you can go the other way and just get an Option, like:

json_value["field"].as_str().and_then(|s| s.parse::<MyType>().ok())

Or, if you are in a method that returns a suitable type of Result, you can do:

json_value["field"].as_str().ok_or(MissingFieldError)?.parse::<MyType>()?
1 Like