How best to capture an enum value, but with a guard to restrict the discriminant value?

⚓ Rust    📅 2025-06-25    👤 surdeus    👁️ 6      

surdeus

Warning

This post was published 47 days ago. The information described in this article may have changed.

I'd like to match for a subset of discriminants in an enum, but also capture the original enum variant (by which I mean discriminant and value together - not sure if I have the terms right). I can't quite figure out how to do both, the reduced example below describes the closest I can get, but in this case clippy doesn't understand the matches! guard and still fails the code with:

error[E0004]: non-exhaustive patterns: `X::A(_)` and `X::C(_)` not covered

...this makes me think I must not be doing this idiomatically. Any suggestions on the right way to work through this pattern?

#[derive(Debug, PartialEq)]
enum X {
    A(i32),
    B(i32),
    C(i32),
}

fn only_add_a_or_c(x: X, v: &mut Vec<X>) {
    match x {
        x if matches!(x,X::A(_) | X::C(_)) => {
            v.push(x);
        },
        X::B(_) => (),
    }
}

fn main() {
    let mut v = Vec::new();

    only_add_a_or_c(X::A(10),&mut v);
    only_add_a_or_c(X::B(20),&mut v);
    only_add_a_or_c(X::C(30),&mut v);

    assert_eq!(v, vec![X::A(10), X::C(30)]);    
}

I understand in this reduced form there are all kinds of workarounds like matching toB(_) first and then matching to everything else, but those kinds of options don't apply to the real case this is reduced from.

3 posts - 2 participants

Read full topic

🏷️ rust_feed