1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
# What `#[derive(Not)]` generates
The derived `Not` implementation simply negates all 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.
## Tuple structs
When deriving for a tuple struct with two fields like this:
```rust
# use derive_more::Not;
#
#[derive(Not)]
struct MyInts(i32, i32);
```
Code like this will be generated:
```rust
# struct MyInts(i32, i32);
impl derive_more::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.
## Regular structs
When deriving for a regular struct with two fields like this:
```rust
# use derive_more::Not;
#
#[derive(Not)]
struct Point2D {
x: i32,
y: i32,
}
```
Code like this will be generated:
```rust
# struct Point2D {
# x: i32,
# y: i32,
# }
impl derive_more::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.
## 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:
```rust
# use derive_more::Not;
#
#[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:
```rust
# enum MixedInts {
# SmallInt(i32),
# BigInt(i64),
# TwoSmallInts(i32, i32),
# NamedSmallInts { x: i32, y: i32 },
# UnsignedOne(u32),
# UnsignedTwo(u32),
# }
impl derive_more::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:
```rust
# use derive_more::Not;
#
#[derive(Not)]
enum EnumWithUnit {
SmallInt(i32),
Unit,
}
```
Code like this will be generated:
```rust
# enum EnumWithUnit {
# SmallInt(i32),
# Unit,
# }
impl derive_more::Not for EnumWithUnit {
type Output = Result<EnumWithUnit, derive_more::UnitError>;
fn not(self) -> Result<EnumWithUnit, derive_more::UnitError> {
match self {
EnumWithUnit::SmallInt(__0) => Ok(EnumWithUnit::SmallInt(__0.not())),
EnumWithUnit::Unit => Err(derive_more::UnitError::new("not")),
}
}
}
```
|