stry_common/utils/fenn/
newtype.rs

1/// A macro for easy creation of [`newtype`]s.
2///
3/// # Note
4///
5/// Newtypes created by this macro are `sealed`, meaning they **do not**
6/// implement [`AsMut`], [`AsRef`], [`Deref`], or [`DerefMut`].
7///
8/// Doing so would invalidate any use of a `newtype`.
9///
10/// [`newtype`]: https://doc.rust-lang.org/rust-by-example/generics/new_types.html
11/// [`AsMut`]: https://doc.rust-lang.org/stable/std/convert/trait.AsMut.html
12/// [`AsRef`]: https://doc.rust-lang.org/stable/std/convert/trait.AsRef.html
13/// [`Deref`]: https://doc.rust-lang.org/stable/std/ops/trait.Deref.html
14/// [`DerefMut`]: https://doc.rust-lang.org/stable/std/ops/trait.DerefMut.html
15#[macro_export]
16macro_rules! newtype {
17    ($( #[$attrs:meta] )* $name:ident $( : $default:ty )?) => {
18        $( #[$attrs] )*
19        #[derive(Debug)]
20        pub struct $name<T $( = $default )?>(pub T);
21
22        impl<T> ::core::default::Default for $name<T>
23        where
24            T: ::core::default::Default,
25        {
26            fn default() -> Self {
27                Self(T::default())
28            }
29        }
30
31        impl<T> ::core::convert::From<T> for $name<T> {
32            fn from(other: T) -> Self {
33                Self(other)
34            }
35        }
36
37        //#region[rgba(186,255,201,0.05)] copy/clone
38        impl<T> ::core::clone::Clone for $name<T>
39        where
40            T: ::core::clone::Clone,
41        {
42            fn clone(&self) -> Self {
43                Self(self.0.clone())
44            }
45        }
46
47        impl<T> ::core::marker::Copy for $name<T>
48        where
49            T: ::core::marker::Copy,
50        {}
51        //#endregion
52
53        //#region [rgba(186,225,255,0.05)] eq/ord
54        impl<T> ::core::cmp::PartialEq for $name<T>
55        where
56            T: ::core::cmp::PartialEq,
57        {
58            fn eq(&self, other: &Self) -> bool {
59                self.0 == other.0
60            }
61        }
62
63        impl<T> ::core::cmp::Eq for $name<T>
64        where
65            T: ::core::cmp::Eq,
66        {}
67
68        impl<T> ::core::cmp::PartialOrd for $name<T>
69        where
70            T: ::core::cmp::PartialOrd,
71        {
72            fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
73                self.0.partial_cmp(&other.0)
74            }
75        }
76
77        impl<T> ::core::cmp::Ord for $name<T>
78        where
79            T: ::core::cmp::Ord,
80        {
81            fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
82                self.0.cmp(&other.0)
83            }
84        }
85        //#endregion
86
87        impl<T> ::core::ops::Not for $name<T>
88        where
89            T: ::core::ops::Not<Output = T>,
90        {
91            type Output = Self;
92
93            fn not(self) -> Self {
94                Self(!self.0)
95            }
96        }
97
98        impl<T> ::core::ops::Neg for $name<T>
99        where
100            T: ::core::ops::Neg<Output = T>,
101        {
102            type Output = Self;
103
104            fn neg(self) -> Self {
105                Self(-self.0)
106            }
107        }
108
109        impl<T> ::core::hash::Hash for $name<T>
110        where
111            T: ::core::hash::Hash,
112        {
113            fn hash<H:>(&self, state: &mut H)
114            where
115                H: ::core::hash::Hasher,
116            {
117                ::core::hash::Hash::hash(&self.0, state)
118            }
119        }
120
121        //#region [rgba(255,179,186,0.05)] operations
122        impl<T> ::core::ops::Add for $name<T>
123        where
124            T: ::core::ops::Add<Output = T>,
125        {
126            type Output = Self;
127
128            fn add(self, other: Self) -> Self {
129                Self(self.0 + other.0)
130            }
131        }
132
133        impl<T> ::core::ops::AddAssign for $name<T>
134        where
135            T: ::core::ops::AddAssign,
136        {
137            fn add_assign(&mut self, other: Self) {
138                self.0 += other.0;
139            }
140        }
141
142        impl<T> ::core::ops::BitAnd for $name<T>
143        where
144            T: ::core::ops::BitAnd<Output = T>,
145        {
146            type Output = Self;
147
148            fn bitand(self, other: Self) -> Self::Output {
149                Self(self.0 & other.0)
150            }
151        }
152
153        impl<T> ::core::ops::BitAndAssign  for $name<T>
154        where
155            T: ::core::ops::BitAndAssign + ::core::ops::BitAnd<Output = T>,
156        {
157            fn bitand_assign(&mut self, other: Self) {
158                self.0 &= other.0
159            }
160        }
161
162        impl<T> ::core::ops::BitOr for $name<T>
163        where
164            T: ::core::ops::BitOr<Output = T>,
165        {
166            type Output = Self;
167
168            fn bitor(self, other: Self) -> Self::Output {
169                Self(self.0 | other.0)
170            }
171        }
172
173        impl<T> ::core::ops::BitOrAssign  for $name<T>
174        where
175            T: ::core::ops::BitOrAssign + ::core::ops::BitOr<Output = T>,
176        {
177            fn bitor_assign(&mut self, other: Self) {
178                self.0 |= other.0
179            }
180        }
181
182        impl<T> ::core::ops::BitXor for $name<T>
183        where
184            T: ::core::ops::BitXor<Output = T>,
185        {
186            type Output = Self;
187
188            fn bitxor(self, other: Self) -> Self::Output {
189                Self(self.0 ^ other.0)
190            }
191        }
192
193        impl<T> ::core::ops::BitXorAssign  for $name<T>
194        where
195            T: ::core::ops::BitXorAssign + ::core::ops::BitXor<Output = T>,
196        {
197            fn bitxor_assign(&mut self, other: Self) {
198                self.0 ^= other.0
199            }
200        }
201
202        impl<T> ::core::ops::Div for $name<T>
203        where
204            T: ::core::ops::Div<Output = T>,
205        {
206            type Output = Self;
207
208            fn div(self, other: Self) -> Self::Output {
209                Self(self.0 / other.0)
210            }
211        }
212
213        impl<T> ::core::ops::DivAssign for $name<T>
214        where
215            T: ::core::ops::DivAssign,
216        {
217            fn div_assign(&mut self, other: Self) {
218                self.0 /= other.0
219            }
220        }
221
222        impl<T> ::core::ops::Mul for $name<T>
223        where
224            T: ::core::ops::Mul<Output = T>,
225        {
226            type Output = Self;
227
228            fn mul(self, other: Self) -> Self::Output {
229                Self(self.0 * other.0)
230            }
231        }
232
233        impl<T> ::core::ops::MulAssign for $name<T>
234        where
235            T: ::core::ops::MulAssign,
236        {
237            fn mul_assign(&mut self, other: Self) {
238                self.0 *= other.0
239            }
240        }
241
242        impl<T> ::core::ops::Rem for $name<T>
243        where
244            T: ::core::ops::Rem<Output = T>,
245        {
246            type Output = Self;
247
248            fn rem(self, other: Self) -> Self::Output {
249                Self(self.0 % other.0)
250            }
251        }
252
253        impl<T> ::core::ops::RemAssign for $name<T>
254        where
255            T: ::core::ops::RemAssign,
256        {
257            fn rem_assign(&mut self, other: Self) {
258                self.0 %= other.0
259            }
260        }
261
262        impl<T> ::core::ops::Sub for $name<T>
263        where
264            T: ::core::ops::Sub<Output = T>,
265        {
266            type Output = Self;
267
268            fn sub(self, other: Self) -> Self::Output {
269                Self(self.0 - other.0)
270            }
271        }
272
273        impl<T> ::core::ops::SubAssign for $name<T>
274        where
275            T: ::core::ops::SubAssign,
276        {
277            fn sub_assign(&mut self, other: Self) {
278                self.0 -= other.0
279            }
280        }
281
282        impl<T> ::core::ops::Shl for $name<T>
283        where
284            T: ::core::ops::Shl<Output = T>,
285        {
286            type Output = Self;
287
288            fn shl(self, other: Self) -> Self::Output {
289                Self(self.0 << other.0)
290            }
291        }
292
293        impl<T> ::core::ops::ShlAssign for $name<T>
294        where
295            T: ::core::ops::ShlAssign,
296        {
297            fn shl_assign(&mut self, other: Self) {
298                self.0 <<= other.0
299            }
300        }
301
302        impl<T> ::core::ops::Shr for $name<T>
303        where
304            T: ::core::ops::Shr<Output = T>,
305        {
306            type Output = Self;
307
308            fn shr(self, other: Self) -> Self::Output {
309                Self(self.0 >> other.0)
310            }
311        }
312
313        impl<T> ::core::ops::ShrAssign for $name<T>
314        where
315            T: ::core::ops::ShrAssign,
316        {
317            fn shr_assign(&mut self, other: Self) {
318                self.0 >>= other.0
319            }
320        }
321        //#endregion
322    };
323}