What #[derive(Not)] generates
The derived Not
implementation simply negates all of the fields of a
struct and returns that as a new instance of the struct.
For enums all fields of the active variant of the enum are negated and a new
instance of the same variant with these negated fields is returned.
1 Tuple structs
When deriving for a tuple struct with two fields like this:
#[derive(Not)] struct MyInts(i32, i32);
Code like this will be generated:
impl ::core::ops::Not for MyInts { type Output = MyInts; fn not(self) -> MyInts { MyInts(self.0.not(), self.1.not()) } }
The behaviour is similar with more or less fields.
2 Regular structs
When deriving for a regular struct with two fields like this:
#[derive(Not)] struct Point2D { x: i32, y: i32, }
Code like this will be generated:
impl ::core::ops::Not for Point2D { type Output = Point2D; fn not(self) -> Point2D { Point2D { x: self.x.not(), y: self.y.not(), } } }
The behaviour is similar with more or less fields.
3 Enums
For each enum variant Not
is derived in a similar way as it would be derived
if it would be its own type.
For instance when deriving Not
for an enum like this:
#[derive(Not)] enum MixedInts { SmallInt(i32), BigInt(i64), TwoSmallInts(i32, i32), NamedSmallInts { x: i32, y: i32 }, UnsignedOne(u32), UnsignedTwo(u32), }
Code like this will be generated:
impl ::core::ops::Not for MixedInts { type Output = MixedInts; fn not(self) -> MixedInts { match self { MixedInts::SmallInt(__0) => MixedInts::SmallInt(__0.not()), MixedInts::BigInt(__0) => MixedInts::BigInt(__0.not()), MixedInts::TwoSmallInts(__0, __1) => MixedInts::TwoSmallInts(__0.not(), __1.not()), MixedInts::NamedSmallInts { x: __0, y: __1 } => { MixedInts::NamedSmallInts { x: __0.not(), y: __1.not(), } } MixedInts::UnsignedOne(__0) => MixedInts::UnsignedOne(__0.not()), MixedInts::UnsignedTwo(__0) => MixedInts::UnsignedTwo(__0.not()), } } }
There is one important thing to remember though.
If you add a unit variant to the enum its return type will change from
EnumType
to Result<EnumType>
.
This is because Unit cannot have Not
implemented.
So, when deriving Not
for an enum like this:
#[derive(Not)] enum EnumWithUnit { SmallInt(i32), Unit, }
Code like this will be generated:
impl ::core::ops::Not for EnumWithUnit { type Output = Result<EnumWithUnit, &'static str>; fn not(self) -> Result<EnumWithUnit, &'static str> { match self { EnumWithUnit::SmallInt(__0) => Ok(EnumWithUnit::SmallInt(__0.not())), EnumWithUnit::Unit => Err("Cannot not() unit variants"), } } }