I am trying to find a good way to convert an Option<String>
to an Option<i8>
.
For example,
use std::str::FromStr;
fn main() {
let some_option: Option<String> = Some("too".to_owned());
let new_option: Option<i8> = some_option.map(|x| i8::from_str(x.as_str()));
}
I thought I could use the turbo fish to explicitly cast the type so something like this:
use std::str::FromStr;
fn main() {
let some_option: Option<String> = Some("too".to_owned());
let new_option: Option<i8> = some_option.map::<Option<i8>>(|x| i8::from_str(x.as_str()));
}
However, the compiler points out this isn't the correct amount of parameters, so I thought this might work, but it doesn't:
use std::str::FromStr;
fn main() {
let some_option: Option<String> = Some("too".to_owned());
let new_option: Option<i8> = some_option.map::<Option<i8>,i8::from_str>();
}
You can use the ok()
and unwrap_or()
functions:
fn test() -> Option<Result<u32, ()>> {
Some(Ok(1))
}
fn main() {
let x: Option<Result<_, _>> = test();
println!("{:?}", x.map(|r| r.ok()).unwrap_or(None));
}
Instead of creating an Option<Result<T, E>>
in the first place, you can combine:
Option::and_then
, which applies a closure that returns an Option
and flattens the result.
Result::ok
, which converts a Result
to an Option
, discarding the error.
fn main() {
let some_option = Some("too".to_owned());
let new_option = some_option.and_then(|x| x.parse::<u8>().ok());
}
You can use the same two tools to answer your direct question:
fn convert<T, E>(a: Option<Result<T, E>>) -> Option<T> {
a.and_then(Result::ok)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With