Let\'s say I have the following Enum
enum MyEnum {
VariantA,
VariantB,
VariantC,
}
I can derive the PartialEq trait for the whole enum by
What I want to do, is derive the trait but only to particular variants and not the whole enum. Is that possible? (or does it even make sense?).
This doesn't really make sense.
Traits are implemented for types. An enum is a type and its variants are its values. Your question is equivalent to asking if you could implement a trait for some String
s but not others.
If it is acceptable for unsupported variants to always return false
, similar to how f32
's PartialEq
implementation returns false
whenever you compare a NaN
value, then you can write that impl by hand:
impl PartialEq for MyEnum {
fn eq(&self, other: &MyEnum) -> bool {
use MyEnum::*;
match (self, other) {
// VariantA and VariantB are supported
(VariantA(value), VariantA(other_value)) => value == other_value,
(VariantB(value), VariantB(other_value)) => value == other_value,
// Any other combinations of variants end up here
_ => false,
}
}
}
Note that you must not implement Eq
this way, since implementations of Eq
may be assumed to be total, which this is not.
Assuming you have a setup like:
#[derive(PartialEq)]
struct VarB{
pub value: u32,
}
#[derive(PartialEq)]
enum MyEnum{
VarA(VarA),
VarB(VarB)
}
VarA comes from a different crate and you can't compile due to it not having derived PartialEq (or any other external trait).
You can solve that with the newtype pattern (assuming you have access to the relevent fields / accessors)
struct MyVarA(VarA);
impl PartialEq for MyVarA{
fn eq(&self, other: &MyVarA) -> bool {
self.0.value == other.0.value
}
fn ne(&self, other: &MyVarA) -> bool {
self.0.value != other.0.value
}
}
#[derive(PartialEq)]
struct VarB{
value: u32,
}
#[derive(PartialEq)]
enum MyEnum{
VarA(MyVarA),
VarB(VarB)
}
further informations: https://doc.rust-lang.org/rust-by-example/generics/new_types.html