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]
351macro_rules! forward_deref_and_mut {
352 ($ty:ty => $target:ty) => {
353 impl ::core::ops::Deref for $ty {
354 type Target = $target;
355
356 fn deref(&self) -> &Self::Target {
357 ::core::ops::Deref::deref(&self.0)
358 }
359 }
360
361 impl ::core::ops::DerefMut for $ty {
362 fn deref_mut(&mut self) -> &mut Self::Target {
363 ::core::ops::DerefMut::deref_mut(&mut self.0)
364 }
365 }
366 };
367
368 ($ty:ty => ref $target:ty) => {
369 impl<'__impl_more_a> ::core::ops::Deref for $ty {
370 type Target = $target;
371
372 fn deref(&self) -> &Self::Target {
373 ::core::ops::Deref::deref(&self.0)
374 }
375 }
376
377 impl<'__impl_more_a> ::core::ops::DerefMut for $ty {
378 fn deref_mut(&mut self) -> &mut Self::Target {
379 ::core::ops::DerefMut::deref_mut(&mut self.0)
380 }
381 }
382 };
383
384 ($ty:ty => $field:ident : $target:ty) => {
385 impl ::core::ops::Deref for $ty {
386 type Target = $target;
387
388 fn deref(&self) -> &Self::Target {
389 ::core::ops::Deref::deref(&self.$field)
390 }
391 }
392
393 impl ::core::ops::DerefMut for $ty {
394 fn deref_mut(&mut self) -> &mut Self::Target {
395 ::core::ops::DerefMut::deref_mut(&mut self.$field)
396 }
397 }
398 };
399
400 ($ty:ty => $field:ident : ref $target:ty) => {
401 impl<'__impl_more_a> ::core::ops::Deref for $ty {
402 type Target = $target;
403
404 fn deref(&self) -> &Self::Target {
405 ::core::ops::Deref::deref(&self.$field)
406 }
407 }
408
409 impl<'__impl_more_a> ::core::ops::DerefMut for $ty {
410 fn deref_mut(&mut self) -> &mut Self::Target {
411 ::core::ops::DerefMut::deref_mut(&mut self.$field)
412 }
413 }
414 };
415}
416
417#[cfg(test)]
418mod tests {
419 #![allow(dead_code)]
420
421 use alloc::{borrow::ToOwned as _, string::String};
422 use core::ops::{Deref, DerefMut};
423
424 fn accepts_string_slice(_: &str) {}
425 fn accepts_mut_string_slice(_: &mut str) {}
426
427 struct Foo1(String);
428 impl_deref_and_mut!(Foo1 => String);
429 static_assertions::assert_impl_all!(
430 Foo1:
431 Deref<Target = String>,
433 DerefMut<Target = String>,
434 );
435
436 struct Foo2(String);
437 forward_deref_and_mut!(Foo2 => ref str);
438 static_assertions::assert_impl_all!(
439 Foo2:
440 Deref,
442 DerefMut,
443 );
444
445 struct SingleGeneric<T>(T);
446 impl_deref!(<T> in SingleGeneric<T> => T);
447 impl_deref_mut!(<T> in SingleGeneric<T>);
448 static_assertions::assert_impl_all!(
449 SingleGeneric<usize>:
450 Deref<Target = usize>,
452 DerefMut<Target = usize>,
453 );
454
455 struct SingleGenericCombined<T>(T);
456 impl_deref_and_mut!(<T> in SingleGenericCombined<T> => T);
457 static_assertions::assert_impl_all!(
458 SingleGenericCombined<usize>:
459 Deref<Target = usize>,
461 DerefMut<Target = usize>,
462 );
463
464 struct DoubleGeneric<T, U> {
465 t: T,
466 _u: U,
467 }
468 impl_deref!(<T, U> in DoubleGeneric<T, U> => t: T);
469 impl_deref_mut!(<T, U> in DoubleGeneric<T, U> => t);
470 static_assertions::assert_impl_all!(
471 DoubleGeneric<usize, u32>:
472 Deref<Target = usize>,
474 DerefMut<Target = usize>,
475 );
476
477 struct DoubleGenericCombined<T, U> {
478 t: T,
479 _u: U,
480 }
481 impl_deref_and_mut!(<T, U> in DoubleGenericCombined<T, U> => t: T);
482 static_assertions::assert_impl_all!(
483 DoubleGenericCombined<usize, u32>:
484 Deref<Target = usize>,
486 DerefMut<Target = usize>,
487 );
488
489 #[test]
490 fn foo2_impls() {
491 let mut foo = Foo2("".to_owned());
492 accepts_string_slice(&foo);
493 accepts_mut_string_slice(&mut foo);
494 }
495
496 struct Foo3 {
497 msg: String,
498 }
499 forward_deref_and_mut!(Foo3 => msg: ref str);
500 static_assertions::assert_impl_all!(
501 Foo3:
502 Deref,
504 DerefMut,
505 );
506
507 #[test]
508 fn foo3_impls() {
509 let mut foo = Foo3 { msg: "".to_owned() };
510 accepts_string_slice(&foo);
511 accepts_mut_string_slice(&mut foo);
512 }
513}