Imagine I have two functions which return Results and would like to select the first result if Ok and otherwise the second result. Something like the following:
fn primary() -> Result<String, ()> {
Err(())
}
fn alternative() -> Result<String, ()> {
Ok("alternative".to_string())
}
fn using_match() -> Result<String, ()> {
Ok(match primary() {
Ok(string) => string,
_ => alternative()?
})
}
I’m struggling to find a way to express this as a chain of combinators. The following doesn’t work for the reason stated in the comment, but it captures the chain structure I’m trying to achieve:
fn combinator_attempt() -> Result<String, ()> {
// this is wrong because the closure must return a String
// v----------------v
Ok(primary().map(|string| string).unwrap_or_else(|_| alternative()?))
}
Is there an idiomatic way to express this? For extra points, what is a good way to select the first Ok (or last Err) from a chain of (three or more) possible operations?
>Solution :
You can use Result::or_else method to make chains:
fn using_match() -> Result<String, ()> {
primary().or_else(|_| alternative())
}
fn chain_three() -> Result<String, ()> {
primary().or_else(|_| alternative()).or_else(|_| third_option())
}
Docs: https://doc.rust-lang.org/std/result/enum.Result.html#method.or_else