Match enum range


#1

Hi

Is there any way to make this work?

#[repr(u32)]
#[derive(PartialOrd, Ord, PartialEq, Eq)]
enum A {
    One = 1,
    Two = 2,
    Three = 3
}

fn main() {
    let x = A::One;
    match x {
        A::One...A::Two => println!("One or Two"),
        _ => println!("The rest")
    }
}

The real enum is much bigger and I don’t want to OR them all.
Currently I solve this by using

match x {
    y if y => .... => ...
}

#2

This works on nightly:

https://play.rust-lang.org/?gist=f6fe10f486175d9c714a32a427260161&version=nightly

I’ve implemented Copy here because contains takes the item by value (why ever), not sure if that fits for you.

Any reason you could not use two equivalent guards though? This works on stable: https://play.rust-lang.org/?gist=c67de2a9abd4a64fe82625a3222e7630&version=stable.


#3

Thanks for the solution but I think you missed my point. It’s the cleaner syntax I want. Your way is basically same (if not worse :slight_smile: ) as
x if x => A::One && x <= A::Two => ....


#4

Right, I did not understand that :slight_smile: Unfortunately, as of https://doc.rust-lang.org/book/second-edition/ch18-03-pattern-syntax.html#matching-ranges-of-values-with-, this won’t work ever probably.


#5

I think wanting this is misguided. It would make the code extremely fragile with respect to changes to the underlying enum.


#6

Well, the error message I get is that the enum must be char or numeric representation in order for this to work, which it is (u32)…


#7

bindgen gave me this enum. Maybe const u32s would have been better in this case.


#8
match x as u32 {
        1...2 => println!("One or Two"),
        _ => println!("The rest")
    }

Infortunately A...B in match is not an expression, so you can’t use A as u32 in there.