1#[macro_export]
33macro_rules! impl_deref {
34 (<$($generic:ident),+> in $this:ty => $target:ty) => {
35 impl <$($generic),+> ::core::ops::Deref for $this {
36 type Target = $target;
37
38 fn deref(&self) -> &Self::Target {
39 &self.0
40 }
41 }
42 };
43
44 (<$($generic:ident),+> in $this:ty => $field:ident : $target:ty) => {
45 impl <$($generic),+> ::core::ops::Deref for $this {
46 type Target = $target;
47
48 fn deref(&self) -> &Self::Target {
49 &self.$field
50 }
51 }
52 };
53
54 ($this:ty => $target:ty) => {
55 impl ::core::ops::Deref for $this {
56 type Target = $target;
57
58 fn deref(&self) -> &Self::Target {
59 &self.0
60 }
61 }
62 };
63
64 ($this:ty => $field:ident : $target:ty) => {
65 impl ::core::ops::Deref for $this {
66 type Target = $target;
67
68 fn deref(&self) -> &Self::Target {
69 &self.$field
70 }
71 }
72 };
73}
74
75#[macro_export]
119macro_rules! impl_deref_mut {
120 (<$($generic:ident),+> in $this:ty) => {
121 impl <$($generic),+> ::core::ops::DerefMut for $this {
122 fn deref_mut(&mut self) -> &mut Self::Target {
123 &mut self.0
124 }
125 }
126 };
127
128 (<$($generic:ident),+> in $this:ty => $field:ident) => {
129 impl <$($generic),+> ::core::ops::DerefMut for $this {
130 fn deref_mut(&mut self) -> &mut Self::Target {
131 &mut self.$field
132 }
133 }
134 };
135
136 ($this:ty) => {
137 impl ::core::ops::DerefMut for $this {
138 fn deref_mut(&mut self) -> &mut Self::Target {
139 &mut self.0
140 }
141 }
142 };
143
144 ($this:ty => $field:ident) => {
145 impl ::core::ops::DerefMut for $this {
146 fn deref_mut(&mut self) -> &mut Self::Target {
147 &mut self.$field
148 }
149 }
150 };
151}
152
153#[macro_export]
184macro_rules! impl_deref_and_mut {
185 (<$($generic:ident),+> in $this:ty => $target:ty) => {
186 impl <$($generic),+> ::core::ops::Deref for $this {
187 type Target = $target;
188
189 fn deref(&self) -> &Self::Target {
190 &self.0
191 }
192 }
193
194 impl <$($generic),+> ::core::ops::DerefMut for $this {
195 fn deref_mut(&mut self) -> &mut Self::Target {
196 &mut self.0
197 }
198 }
199 };
200
201 (<$($generic:ident),+> in $this:ty => $field:ident : $target:ty) => {
202 impl <$($generic),+> ::core::ops::Deref for $this {
203 type Target = $target;
204
205 fn deref(&self) -> &Self::Target {
206 &self.$field
207 }
208 }
209
210 impl <$($generic),+> ::core::ops::DerefMut for $this {
211 fn deref_mut(&mut self) -> &mut Self::Target {
212 &mut self.$field
213 }
214 }
215 };
216
217 ($this:ty => $target:ty) => {
218 impl ::core::ops::Deref for $this {
219 type Target = $target;
220
221 fn deref(&self) -> &Self::Target {
222 &self.0
223 }
224 }
225
226 impl ::core::ops::DerefMut for $this {
227 fn deref_mut(&mut self) -> &mut Self::Target {
228 &mut self.0
229 }
230 }
231 };
232
233 ($this:ty => $field:ident : $target:ty) => {
234 impl ::core::ops::Deref for $this {
235 type Target = $target;
236
237 fn deref(&self) -> &Self::Target {
238 &self.$field
239 }
240 }
241
242 impl ::core::ops::DerefMut for $this {
243 fn deref_mut(&mut self) -> &mut Self::Target {
244 &mut self.$field
245 }
246 }
247 };
248}
249
250#[macro_export]
275macro_rules! forward_deref_and_mut {
276 ($ty:ty => $target:ty) => {
277 impl ::core::ops::Deref for $ty {
278 type Target = $target;
279
280 fn deref(&self) -> &Self::Target {
281 ::core::ops::Deref::deref(&self.0)
282 }
283 }
284
285 impl ::core::ops::DerefMut for $ty {
286 fn deref_mut(&mut self) -> &mut Self::Target {
287 ::core::ops::DerefMut::deref_mut(&mut self.0)
288 }
289 }
290 };
291
292 ($ty:ty => ref $target:ty) => {
293 impl<'__impl_more_a> ::core::ops::Deref for $ty {
294 type Target = $target;
295
296 fn deref(&self) -> &Self::Target {
297 ::core::ops::Deref::deref(&self.0)
298 }
299 }
300
301 impl<'__impl_more_a> ::core::ops::DerefMut for $ty {
302 fn deref_mut(&mut self) -> &mut Self::Target {
303 ::core::ops::DerefMut::deref_mut(&mut self.0)
304 }
305 }
306 };
307
308 ($ty:ty => $field:ident : $target:ty) => {
309 impl ::core::ops::Deref for $ty {
310 type Target = $target;
311
312 fn deref(&self) -> &Self::Target {
313 ::core::ops::Deref::deref(&self.$field)
314 }
315 }
316
317 impl ::core::ops::DerefMut for $ty {
318 fn deref_mut(&mut self) -> &mut Self::Target {
319 ::core::ops::DerefMut::deref_mut(&mut self.$field)
320 }
321 }
322 };
323
324 ($ty:ty => $field:ident : ref $target:ty) => {
325 impl<'__impl_more_a> ::core::ops::Deref for $ty {
326 type Target = $target;
327
328 fn deref(&self) -> &Self::Target {
329 ::core::ops::Deref::deref(&self.$field)
330 }
331 }
332
333 impl<'__impl_more_a> ::core::ops::DerefMut for $ty {
334 fn deref_mut(&mut self) -> &mut Self::Target {
335 ::core::ops::DerefMut::deref_mut(&mut self.$field)
336 }
337 }
338 };
339}
340
341#[cfg(test)]
342mod tests {
343 #![allow(dead_code)]
344
345 use alloc::{borrow::ToOwned as _, string::String};
346 use core::ops::{Deref, DerefMut};
347
348 fn accepts_string_slice(_: &str) {}
349 fn accepts_mut_string_slice(_: &mut str) {}
350
351 struct Foo1(String);
352 impl_deref_and_mut!(Foo1 => String);
353 static_assertions::assert_impl_all!(
354 Foo1:
355 Deref<Target = String>,
357 DerefMut<Target = String>,
358 );
359
360 struct Foo2(String);
361 forward_deref_and_mut!(Foo2 => ref str);
362 static_assertions::assert_impl_all!(
363 Foo2:
364 Deref,
366 DerefMut,
367 );
368
369 struct SingleGeneric<T>(T);
370 impl_deref!(<T> in SingleGeneric<T> => T);
371 impl_deref_mut!(<T> in SingleGeneric<T>);
372 static_assertions::assert_impl_all!(
373 SingleGeneric<usize>:
374 Deref<Target = usize>,
376 DerefMut<Target = usize>,
377 );
378
379 struct SingleGenericCombined<T>(T);
380 impl_deref_and_mut!(<T> in SingleGenericCombined<T> => T);
381 static_assertions::assert_impl_all!(
382 SingleGenericCombined<usize>:
383 Deref<Target = usize>,
385 DerefMut<Target = usize>,
386 );
387
388 struct DoubleGeneric<T, U> {
389 t: T,
390 _u: U,
391 }
392 impl_deref!(<T, U> in DoubleGeneric<T, U> => t: T);
393 impl_deref_mut!(<T, U> in DoubleGeneric<T, U> => t);
394 static_assertions::assert_impl_all!(
395 DoubleGeneric<usize, u32>:
396 Deref<Target = usize>,
398 DerefMut<Target = usize>,
399 );
400
401 struct DoubleGenericCombined<T, U> {
402 t: T,
403 _u: U,
404 }
405 impl_deref_and_mut!(<T, U> in DoubleGenericCombined<T, U> => t: T);
406 static_assertions::assert_impl_all!(
407 DoubleGenericCombined<usize, u32>:
408 Deref<Target = usize>,
410 DerefMut<Target = usize>,
411 );
412
413 #[test]
414 fn foo2_impls() {
415 let mut foo = Foo2("".to_owned());
416 accepts_string_slice(&foo);
417 accepts_mut_string_slice(&mut foo);
418 }
419
420 struct Foo3 {
421 msg: String,
422 }
423 forward_deref_and_mut!(Foo3 => msg: ref str);
424 static_assertions::assert_impl_all!(
425 Foo3:
426 Deref,
428 DerefMut,
429 );
430
431 #[test]
432 fn foo3_impls() {
433 let mut foo = Foo3 { msg: "".to_owned() };
434 accepts_string_slice(&foo);
435 accepts_mut_string_slice(&mut foo);
436 }
437}