summaryrefslogtreecommitdiffstats
path: root/third_party/rust/derive_more-impl/doc/not.md
blob: 9997c085ab42b98dfb05a54a55699ede297107a5 (plain)
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 ::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.




## 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 ::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.




## 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 ::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:

```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 ::core::ops::Not for EnumWithUnit {
    type Output = Result<EnumWithUnit, ::derive_more::ops::UnitError>;
    fn not(self) -> Result<EnumWithUnit, ::derive_more::ops::UnitError> {
        match self {
            EnumWithUnit::SmallInt(__0) => Ok(EnumWithUnit::SmallInt(__0.not())),
            EnumWithUnit::Unit => Err(::derive_more::ops::UnitError::new("not")),
        }
    }
}
```