1#[macro_export]
42macro_rules! impl_deref {
43 (<$($generic:ident),+> in $($rest:tt)+) => {
44 $crate::impl_deref!(@impl [$($generic),+] $($rest)+);
45 };
46
47 (<const $($rest:tt)+) => {
48 $crate::impl_deref!(@parse impl_deref [const] $($rest)+);
49 };
50
51 (<$generic:ident, $($rest:tt)+) => {
52 $crate::impl_deref!(@parse impl_deref [$generic,] $($rest)+);
53 };
54
55 (@parse $macro:ident [$($generic:tt)*] > in $($rest:tt)+) => {
56 $crate::$macro!(@impl [$($generic)*] $($rest)+);
57 };
58
59 (@parse $macro:ident [$($generic:tt)*] $next:tt $($rest:tt)+) => {
60 $crate::impl_deref!(@parse $macro [$($generic)* $next] $($rest)+);
61 };
62
63 (@impl [$($generic:tt)+] $this:ty => $target:ty) => {
64 impl <$($generic)+> ::core::ops::Deref for $this {
65 type Target = $target;
66
67 fn deref(&self) -> &Self::Target {
68 &self.0
69 }
70 }
71 };
72
73 (@impl [$($generic:tt)+] $this:ty => $field:ident : $target:ty) => {
74 impl <$($generic)+> ::core::ops::Deref for $this {
75 type Target = $target;
76
77 fn deref(&self) -> &Self::Target {
78 &self.$field
79 }
80 }
81 };
82
83 ($this:ty => $target:ty) => {
84 impl ::core::ops::Deref for $this {
85 type Target = $target;
86
87 fn deref(&self) -> &Self::Target {
88 &self.0
89 }
90 }
91 };
92
93 ($this:ty => $field:ident : $target:ty) => {
94 impl ::core::ops::Deref for $this {
95 type Target = $target;
96
97 fn deref(&self) -> &Self::Target {
98 &self.$field
99 }
100 }
101 };
102}
103
104#[macro_export]
160macro_rules! impl_deref_mut {
161 (<$($generic:ident),+> in $($rest:tt)+) => {
162 $crate::impl_deref_mut!(@impl [$($generic),+] $($rest)+);
163 };
164
165 (<const $($rest:tt)+) => {
166 $crate::impl_deref!(@parse impl_deref_mut [const] $($rest)+);
167 };
168
169 (<$generic:ident, $($rest:tt)+) => {
170 $crate::impl_deref!(@parse impl_deref_mut [$generic,] $($rest)+);
171 };
172
173 (@impl [$($generic:tt)+] $this:ty) => {
174 impl <$($generic)+> ::core::ops::DerefMut for $this {
175 fn deref_mut(&mut self) -> &mut Self::Target {
176 &mut self.0
177 }
178 }
179 };
180
181 (@impl [$($generic:tt)+] $this:ty => $field:ident) => {
182 impl <$($generic)+> ::core::ops::DerefMut for $this {
183 fn deref_mut(&mut self) -> &mut Self::Target {
184 &mut self.$field
185 }
186 }
187 };
188
189 ($this:ty) => {
190 impl ::core::ops::DerefMut for $this {
191 fn deref_mut(&mut self) -> &mut Self::Target {
192 &mut self.0
193 }
194 }
195 };
196
197 ($this:ty => $field:ident) => {
198 impl ::core::ops::DerefMut for $this {
199 fn deref_mut(&mut self) -> &mut Self::Target {
200 &mut self.$field
201 }
202 }
203 };
204}
205
206#[macro_export]
248macro_rules! impl_deref_and_mut {
249 (<$($generic:ident),+> in $($rest:tt)+) => {
250 $crate::impl_deref_and_mut!(@impl [$($generic),+] $($rest)+);
251 };
252
253 (<const $($rest:tt)+) => {
254 $crate::impl_deref!(@parse impl_deref_and_mut [const] $($rest)+);
255 };
256
257 (<$generic:ident, $($rest:tt)+) => {
258 $crate::impl_deref!(@parse impl_deref_and_mut [$generic,] $($rest)+);
259 };
260
261 (@impl [$($generic:tt)+] $this:ty => $target:ty) => {
262 impl <$($generic)+> ::core::ops::Deref for $this {
263 type Target = $target;
264
265 fn deref(&self) -> &Self::Target {
266 &self.0
267 }
268 }
269
270 impl <$($generic)+> ::core::ops::DerefMut for $this {
271 fn deref_mut(&mut self) -> &mut Self::Target {
272 &mut self.0
273 }
274 }
275 };
276
277 (@impl [$($generic:tt)+] $this:ty => $field:ident : $target:ty) => {
278 impl <$($generic)+> ::core::ops::Deref for $this {
279 type Target = $target;
280
281 fn deref(&self) -> &Self::Target {
282 &self.$field
283 }
284 }
285
286 impl <$($generic)+> ::core::ops::DerefMut for $this {
287 fn deref_mut(&mut self) -> &mut Self::Target {
288 &mut self.$field
289 }
290 }
291 };
292
293 ($this:ty => $target:ty) => {
294 impl ::core::ops::Deref for $this {
295 type Target = $target;
296
297 fn deref(&self) -> &Self::Target {
298 &self.0
299 }
300 }
301
302 impl ::core::ops::DerefMut for $this {
303 fn deref_mut(&mut self) -> &mut Self::Target {
304 &mut self.0
305 }
306 }
307 };
308
309 ($this:ty => $field:ident : $target:ty) => {
310 impl ::core::ops::Deref for $this {
311 type Target = $target;
312
313 fn deref(&self) -> &Self::Target {
314 &self.$field
315 }
316 }
317
318 impl ::core::ops::DerefMut for $this {
319 fn deref_mut(&mut self) -> &mut Self::Target {
320 &mut self.$field
321 }
322 }
323 };
324}
325
326#[macro_export]
363macro_rules! forward_deref_and_mut {
364 (<$($generic:ident),+> in $($rest:tt)+) => {
365 $crate::forward_deref_and_mut!(@impl [$($generic),+] $($rest)+);
366 };
367
368 (<const $($rest:tt)+) => {
369 $crate::__impl_more_parse_generics!(@parse forward_deref_and_mut [] [] const $($rest)+);
370 };
371
372 (<$generic:ident, $($rest:tt)+) => {
373 $crate::__impl_more_parse_generics!(@parse forward_deref_and_mut [] [] $generic, $($rest)+);
374 };
375
376 (@impl [$($generic:tt)+] $ty:ty => $target:ty) => {
377 impl <$($generic)+> ::core::ops::Deref for $ty {
378 type Target = $target;
379
380 fn deref(&self) -> &Self::Target {
381 ::core::ops::Deref::deref(&self.0)
382 }
383 }
384
385 impl <$($generic)+> ::core::ops::DerefMut for $ty {
386 fn deref_mut(&mut self) -> &mut Self::Target {
387 ::core::ops::DerefMut::deref_mut(&mut self.0)
388 }
389 }
390 };
391
392 (@impl [$($generic:tt)+] $ty:ty => ref $target:ty) => {
393 impl<'__impl_more_a, $($generic)+> ::core::ops::Deref for $ty {
394 type Target = $target;
395
396 fn deref(&self) -> &Self::Target {
397 ::core::ops::Deref::deref(&self.0)
398 }
399 }
400
401 impl<'__impl_more_a, $($generic)+> ::core::ops::DerefMut for $ty {
402 fn deref_mut(&mut self) -> &mut Self::Target {
403 ::core::ops::DerefMut::deref_mut(&mut self.0)
404 }
405 }
406 };
407
408 (@impl [$($generic:tt)+] $ty:ty => $field:ident : $target:ty) => {
409 impl <$($generic)+> ::core::ops::Deref for $ty {
410 type Target = $target;
411
412 fn deref(&self) -> &Self::Target {
413 ::core::ops::Deref::deref(&self.$field)
414 }
415 }
416
417 impl <$($generic)+> ::core::ops::DerefMut for $ty {
418 fn deref_mut(&mut self) -> &mut Self::Target {
419 ::core::ops::DerefMut::deref_mut(&mut self.$field)
420 }
421 }
422 };
423
424 (@impl [$($generic:tt)+] $ty:ty => $field:ident : ref $target:ty) => {
425 impl<'__impl_more_a, $($generic)+> ::core::ops::Deref for $ty {
426 type Target = $target;
427
428 fn deref(&self) -> &Self::Target {
429 ::core::ops::Deref::deref(&self.$field)
430 }
431 }
432
433 impl<'__impl_more_a, $($generic)+> ::core::ops::DerefMut for $ty {
434 fn deref_mut(&mut self) -> &mut Self::Target {
435 ::core::ops::DerefMut::deref_mut(&mut self.$field)
436 }
437 }
438 };
439
440 ($ty:ty => $target:ty) => {
441 impl ::core::ops::Deref for $ty {
442 type Target = $target;
443
444 fn deref(&self) -> &Self::Target {
445 ::core::ops::Deref::deref(&self.0)
446 }
447 }
448
449 impl ::core::ops::DerefMut for $ty {
450 fn deref_mut(&mut self) -> &mut Self::Target {
451 ::core::ops::DerefMut::deref_mut(&mut self.0)
452 }
453 }
454 };
455
456 ($ty:ty => ref $target:ty) => {
457 impl<'__impl_more_a> ::core::ops::Deref for $ty {
458 type Target = $target;
459
460 fn deref(&self) -> &Self::Target {
461 ::core::ops::Deref::deref(&self.0)
462 }
463 }
464
465 impl<'__impl_more_a> ::core::ops::DerefMut for $ty {
466 fn deref_mut(&mut self) -> &mut Self::Target {
467 ::core::ops::DerefMut::deref_mut(&mut self.0)
468 }
469 }
470 };
471
472 ($ty:ty => $field:ident : $target:ty) => {
473 impl ::core::ops::Deref for $ty {
474 type Target = $target;
475
476 fn deref(&self) -> &Self::Target {
477 ::core::ops::Deref::deref(&self.$field)
478 }
479 }
480
481 impl ::core::ops::DerefMut for $ty {
482 fn deref_mut(&mut self) -> &mut Self::Target {
483 ::core::ops::DerefMut::deref_mut(&mut self.$field)
484 }
485 }
486 };
487
488 ($ty:ty => $field:ident : ref $target:ty) => {
489 impl<'__impl_more_a> ::core::ops::Deref for $ty {
490 type Target = $target;
491
492 fn deref(&self) -> &Self::Target {
493 ::core::ops::Deref::deref(&self.$field)
494 }
495 }
496
497 impl<'__impl_more_a> ::core::ops::DerefMut for $ty {
498 fn deref_mut(&mut self) -> &mut Self::Target {
499 ::core::ops::DerefMut::deref_mut(&mut self.$field)
500 }
501 }
502 };
503}
504
505#[cfg(test)]
506mod tests {
507 #![allow(dead_code)]
508
509 use alloc::{borrow::ToOwned as _, string::String};
510 use core::ops::{Deref, DerefMut};
511
512 fn accepts_string_slice(_: &str) {}
513 fn accepts_mut_string_slice(_: &mut str) {}
514
515 struct Foo1(String);
516 impl_deref_and_mut!(Foo1 => String);
517 static_assertions::assert_impl_all!(
518 Foo1:
519 Deref<Target = String>,
521 DerefMut<Target = String>,
522 );
523
524 struct Foo2(String);
525 forward_deref_and_mut!(Foo2 => ref str);
526 static_assertions::assert_impl_all!(
527 Foo2:
528 Deref,
530 DerefMut,
531 );
532
533 struct SingleGeneric<T>(T);
534 impl_deref!(<T> in SingleGeneric<T> => T);
535 impl_deref_mut!(<T> in SingleGeneric<T>);
536 static_assertions::assert_impl_all!(
537 SingleGeneric<usize>:
538 Deref<Target = usize>,
540 DerefMut<Target = usize>,
541 );
542
543 struct SingleGenericCombined<T>(T);
544 impl_deref_and_mut!(<T> in SingleGenericCombined<T> => T);
545 static_assertions::assert_impl_all!(
546 SingleGenericCombined<usize>:
547 Deref<Target = usize>,
549 DerefMut<Target = usize>,
550 );
551
552 struct DoubleGeneric<T, U> {
553 t: T,
554 _u: U,
555 }
556 impl_deref!(<T, U> in DoubleGeneric<T, U> => t: T);
557 impl_deref_mut!(<T, U> in DoubleGeneric<T, U> => t);
558 static_assertions::assert_impl_all!(
559 DoubleGeneric<usize, u32>:
560 Deref<Target = usize>,
562 DerefMut<Target = usize>,
563 );
564
565 struct DoubleGenericCombined<T, U> {
566 t: T,
567 _u: U,
568 }
569 impl_deref_and_mut!(<T, U> in DoubleGenericCombined<T, U> => t: T);
570 static_assertions::assert_impl_all!(
571 DoubleGenericCombined<usize, u32>:
572 Deref<Target = usize>,
574 DerefMut<Target = usize>,
575 );
576
577 #[test]
578 fn foo2_impls() {
579 let mut foo = Foo2("".to_owned());
580 accepts_string_slice(&foo);
581 accepts_mut_string_slice(&mut foo);
582 }
583
584 struct Foo3 {
585 msg: String,
586 }
587 forward_deref_and_mut!(Foo3 => msg: ref str);
588 static_assertions::assert_impl_all!(
589 Foo3:
590 Deref,
592 DerefMut,
593 );
594
595 #[test]
596 fn foo3_impls() {
597 let mut foo = Foo3 { msg: "".to_owned() };
598 accepts_string_slice(&foo);
599 accepts_mut_string_slice(&mut foo);
600 }
601}