Arkaitz Jimenez
Arkaitz Jimenez

Reputation: 23178

Match on either an error or an empty result

I have a function that returns Result<Vec<&str>, String> for a list of nodes. My intention is to check for an error or an empty vector to return early, or continue if there there is a list.

This is what I am trying, among other things, but the compiler complains about the type of x.

let nodes = list_nodes(client, &service);
match nodes {
    Err(e) => {
        println!("Unable to list nodes: {:?}", e);
        return;
    },
    Ok(x) if x.as_slice() == []  => {
        println!("No nodes found for service: {}", service);
        return;
    }
    _ => {}
}

The error is:

error[E0282]: type annotations needed
  --> src/main.rs:28:18
   |
28 |         Ok(x) if x.as_slice() == []  => {
   |                  ^^^^^^^^^^^^^^^^^^ cannot infer type for `A`

Upvotes: 0

Views: 4990

Answers (1)

Peter Hall
Peter Hall

Reputation: 58735

The problem is actually that it can't infer the type of []. The type-checker cannot assume that [] here has the same type as x.as_slice() because the PartialEq trait (where == comes from) allows instances where the right hand side is of a different type to the left. You can easily solve it by looking at the slice's length instead, or checking if the slice is empty with is_empty():

match nodes {
    Err(e) => {
        println!("Unable to list nodes: {:?}", e);
        return;
    },
    Ok(ref x) if x.as_slice().is_empty() => {
        println!("No nodes found for service: {}", service);
        return;
    }
    _ => {}
}

Also, taking a reference to x (with ref x like I've done above) will prevent another error that you're likely to get, avoiding moving x when it is still owned by nodes.

Upvotes: 3

Related Questions