How to compare 2 enum variables?

Below is my code to compare 2 enum variables in Rust.

I uploaded the code into playground here..

Pretty straightforward, I just want to use equal operator (==) to compare both enum variable. Thank you in advance.

my enum:

use std::fmt::Display;

#[derive(Display)]
enum Fruits {
    Apple, 
    Orange,
}
// I try to use ToString but Rust cannot find derive macro `Display` in this scope
// ERROR: 
// doesn't satisfy `Fruits: ToString`
// doesn't satisfy `Fruits: std::fmt::Display`

// had to implement PartialEq for Fruits
impl PartialEq for Fruits {
    fn eq(&self, other: &Self) -> bool {
        self.to_string() == other.to_string()
        // here, I'm trying to use string conversion to compare both enum
        // it displays an error: 
        // method cannot be called on `&Fruits` due to unsatisfied trait bounds
    }
}

my main.rs:

fn main(){
    let a = Fruits::Apple;
    let b = Fruits::Orange;
    let c = Fruits::Apple;
    
    if a == c {
        println!("Correct! A equals with C !");
    }
    
    
     if a != b {
        println!("Correct! A is not equal with B !");
    }
    
}

Derive Eq and PartialEq in the enum.

How to do that ? I already have PartialEq implementation, but I'm confused how to implement to_string() to enum as well

Instead of

#[derive(Display)]
enum Fruits {
    Apple, 
    Orange,
}

Use

#[derive(Display, PartialEq, Eq)]
enum Fruits {
    Apple, 
    Orange,
}

... which allows you to compare enums directly with ==. No expensive string conversion necessary.

1 Like

Don't implement PartialEq by comparing string values, instead just derive it like so:

#[derive(PartialEq, Eq)]
enum Fruits {
    Apple, 
    Orange,
}

Playground link.

If you want your enum to also implement Display, you can implement it manually (Display cannot be automatically derived), for example like this:

use std::fmt;

impl fmt::Display for Fruits {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Fruits::Apple => write!(f, "apple"),
            Fruits::Orange => write!(f, "orange"),
        }
    }
}

Then you can use this to, for example, format Fruites values in println!() invocations:

fn main() {
    let a = Fruits::Apple;
    let b = Fruits::Orange;
    let c = Fruits::Apple;

    println!("a is an {}, b is an {}, c is an {}", a, b, c);
    // prints: a is an apple, b is an orange, c is an apple
}

Playground link.

But again, using the Display impl for implementing PartialEq is likely not what you want to do.

8 Likes

Of course there are crates that can do that, like Strum.

1 Like

As others have said, using #[derive(PartialEq)] works great, but if you want to know how to implement PartialEq on enums yourself without deriving it you need to use match:

enum Fruits {
    Apple, 
    Orange,
}

impl PartialEq for Fruits {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (Self::Apple, Self::Apple) | (Self::Orange, Self::Orange) => true,
            _ => false,
        }
    }
}
1 Like

What about matches!()?

impl PartialEq for Fruits {
    fn eq(&self, other: &Self) -> bool {
        matches!(
            (self, other),
            (Self::Apple, Self::Apple) | (Self::Orange, Self::Orange),
        )
    }
}
1 Like