Graeme
Graeme

Reputation: 427

impl PartialEq for an Enum so that multiple variants are equal

I would like to define an enum where two different values are equal, however I want to do it without having to explicitly write out all the match cases for Test::B == Test::B, Test::C == Test::C.

pub enum Test {
    A,
    B,
    C,
    AlsoA,
}

Maybe something like this, but without having to write out the comment marked part

impl PartialEq for Test {
    fn eq(&self, other: &Test) -> bool {
        match (self, other) {
            (&Test::A, &Test::AlsoA) | (&Test::AlsoA, &Test::A) => true,

            // But without this part -------------------
            (&Test::A, &Test::A) => true,
            (&Test::B, &Test::B) => true,
            (&Test::C, &Test::C) => true,
            (&Test::AlsoA, &Test::AlsoA) => true,
            // -----------------------------------------

            _ => false,
        }
    }
}

Upvotes: 2

Views: 1517

Answers (1)

Dogbert
Dogbert

Reputation: 222288

You can add #[repr(T)] to the enum (where T is an integer type), and then compare their as T values:

#[derive(Copy, Clone)]
#[repr(u8)]
pub enum Test {
    A,
    B,
    C,
    AlsoA,
}

impl PartialEq for Test {
    fn eq(&self, other: &Test) -> bool {
        match (self, other) {
            (&Test::A, &Test::AlsoA) |
            (&Test::AlsoA, &Test::A) => true,
            (x, y) => *x as u8 == *y as u8,
        }
    }
}

fn main() {
    use Test::*;
    assert!(A == A);
    assert!(B == B);
    assert!(C == C);
    assert!(AlsoA == AlsoA);
    assert!(A == AlsoA);
    assert!(AlsoA == A);
}

This also answers your second question: just add a #[repr(T)] and then use as T.

Upvotes: 7

Related Questions