Reputation: 3424
I have a struct that is an API endpoint, so I can't change its structure
struct Response {
error: Option<String>,
results: Vec<String>,
}
If error
is Some
, that means it failed server side.
I have a function that returns the struct:
fn get_results() -> Result<Response, String> {
unimplemented!()
}
Is it possible to match the get_results
Result
error, and the optional Response.error
in the same match
branch?
This was my attempt:
fn example() {
let ret = get_results();
match ret.map(|resp| resp.error.map_or_else(|| Ok(resp.results), |e| Err(e))) {
Err(e) => {
println!("Error: {}", &e);
}
Ok(results) => {
//Handle results
}
}
}
But it fails:
error[E0382]: use of moved value: `resp`
--> src/lib.rs:12:49
|
12 | match ret.map(|resp| resp.error.map_or_else(|| Ok(resp.results), |e| Err(e))) {
| ---------- ^^ ---- use occurs due to use in closure
| | |
| | value used here after move
| value moved here
|
= note: move occurs because `resp.error` has type `std::option::Option<std::string::String>`, which does not implement the `Copy` trait
Upvotes: 2
Views: 324
Reputation: 3728
With the Rust version from 2021 your program runs now as is.
Still, I would prefer the let-else syntax because it makes the program clearer:
fn example() {
let ret = get_results();
let Ok(results) = ret else { println!("Error: {}", ret.err().unwrap()); return; };
// handle results here…
}
Upvotes: 0
Reputation: 4288
If the error field is public, you can do something like this:
match resp {
Err(s) | Ok(Response { error: Some(s), .. }) => println!("Error: {}", s),
Ok(Response { error: None, results }) => println!("Responses: {:?}", results)
}
This shows how powerful Rust's match statements can be.
Playground of a simplified example
Upvotes: 3
Reputation: 1245
You can transform a response into a result like this:
match resp.error {
Some(e) => Err(e),
None => Ok(resp.results),
}
You can flatten a nested result with and_then
. Put together, it gives this:
ret.and_then(|resp| match resp.error {
Some(e) => Err(e),
None => Ok(resp.results),
})
Upvotes: 4