wrapper_lite/
lib.rs

1//! Helper macro for creating a wrapper over any type (new-type idiom).
2
3#![no_std]
4
5// For test only
6extern crate alloc;
7
8#[macro_export]
9/// Helper macro for creating a wrapper over any type (new-type idiom).
10///
11/// This is a shortcut for using the `wrapper!` macro with the most common impls
12/// (`AsRef`, `Borrow`, `From`).
13///
14/// ```rust
15/// # use wrapper_lite::*;
16/// general_wrapper! {
17///     #[derive(Debug, Clone, Copy)]
18///     pub ExampleWrapper<'a, P>(pub(crate) &'a P)
19/// }
20/// # fn assert_impls_ExampleWrapper<P: core::fmt::Debug>() {
21/// #    _assert_impl_debug::<ExampleWrapper<'_, P>>();
22/// #    _assert_impl_as_ref::<ExampleWrapper<'_, P>, _>();
23/// #    // _assert_impl_as_mut::<ExampleWrapper<'_, P>, _>();
24/// #    _assert_impl_borrow::<ExampleWrapper<'_, P>, &P>();
25/// #    // _assert_impl_deref::<ExampleWrapper<'_, P>, _>();
26/// #    // _assert_impl_deref_mut::<ExampleWrapper<'_, P>, _>();
27/// #    _assert_impl_from::<ExampleWrapper<'_, P>, &P>();
28/// # }
29/// ```
30///
31/// This is equivalent to using the `wrapper!` macro with the following
32/// attributes:
33///
34/// ```rust,ignore
35/// wrapper! {
36///     #[wrapper_impl(AsRef)]
37///     #[wrapper_impl(Borrow)]
38///     #[wrapper_impl(From)]
39///     #[derive(Debug, Clone, Copy)]
40///     pub ExampleWrapper<'a, P>(pub(crate) &'a P)
41/// }
42/// ```
43///
44/// You can certainly add attributes like `#[wrapper_impl(Deref)]` to implement
45/// other traits based on the preset ones.
46///
47/// ```rust
48/// # use wrapper_lite::*;
49/// general_wrapper! {
50///     #[wrapper_impl(Deref)]
51///     #[derive(Debug, Clone, Copy)]
52///     pub ExampleWrapper<'a, P>(pub(crate) &'a P)
53/// }
54/// # fn assert_impls_ExampleWrapper<P: core::fmt::Debug>() {
55/// #    _assert_impl_debug::<ExampleWrapper<'_, P>>();
56/// #    _assert_impl_as_ref::<ExampleWrapper<'_, P>, _>();
57/// #    // _assert_impl_as_mut::<ExampleWrapper<'_, P>, _>();
58/// #    _assert_impl_borrow::<ExampleWrapper<'_, P>, &P>();
59/// #    _assert_impl_deref::<ExampleWrapper<'_, P>, _>();
60/// #    // _assert_impl_deref_mut::<ExampleWrapper<'_, P>, _>();
61/// #    _assert_impl_from::<ExampleWrapper<'_, P>, &P>();
62/// # }
63/// ```
64///
65/// See [`wrapper!`] for more details.
66macro_rules! general_wrapper {
67    ($($tt:tt)+) => {
68        $crate::wrapper! {
69            #[wrapper_impl(AsRef)]
70            #[wrapper_impl(Borrow)]
71            #[wrapper_impl(From)]
72            $($tt)+
73        }
74    };
75}
76
77#[macro_export]
78/// Helper macro for creating a wrapper over any type (new-type idom).
79///
80/// # Usage: basic
81///
82/// ```rust
83/// # use wrapper_lite::*;
84/// wrapper! {
85///     #[wrapper_impl(AsRef)]
86///     #[wrapper_impl(AsMut)]
87///     #[wrapper_impl(Borrow)]
88///     // #[wrapper_impl(Deref)]
89///     #[wrapper_impl(DerefMut)]
90///     #[wrapper_impl(From)]
91///     #[derive(Debug, Clone, Copy)]
92///     pub ExampleWrapper<'a, P>(pub(crate) &'a P)
93/// }
94/// # fn assert_impls_ExampleWrapper<P: core::fmt::Debug>() {
95/// #    _assert_impl_debug::<ExampleWrapper<'_, P>>();
96/// #    _assert_impl_as_ref::<ExampleWrapper<'_, P>, _>();
97/// #    _assert_impl_as_mut::<ExampleWrapper<'_, P>, _>();
98/// #    _assert_impl_borrow::<ExampleWrapper<'_, P>, &P>();
99/// #    _assert_impl_deref::<ExampleWrapper<'_, P>, _>();
100/// #    _assert_impl_deref_mut::<ExampleWrapper<'_, P>, _>();
101/// #    _assert_impl_from::<ExampleWrapper<'_, P>, &P>();
102/// # }
103/// ```
104///
105/// Generates const accessor methods for wrapper types implementing `AsRef` and
106/// `AsMut` traits.
107///
108/// For types implementing `AsRef`, this creates a const method `as_inner` that
109/// returns a reference to the wrapped value. For types implementing `AsMut`,
110/// this creates a const method `as_inner_mut` that returns a mutable reference
111/// to the wrapped value.
112///
113/// Additionally generates a const constructor method `const_from` for the
114/// wrapper type, using the same visibility as the inner field. When the `From`
115/// trait is implemented, also generates a public const method `from`.
116///
117/// ## Usage: advanced
118///
119/// You can also create a wrapper type with a struct with multiple fields,
120/// especially when some lifetime markers or generics markers are needed.
121///
122/// ```rust
123/// # use wrapper_lite::*;
124/// wrapper! {
125///     #[wrapper_impl(AsMut)]
126///     #[wrapper_impl(AsRef)]
127///     #[wrapper_impl(Borrow)]
128///     #[wrapper_impl(DerefMut)]
129///     #[wrapper_impl(From)]
130///     #[derive(Debug)]
131///     #[repr(transparent)]
132///     pub struct ExampleWrapperComplex<'a, 'b, P> {
133///         inner: P,
134///         _a: ::core::marker::PhantomData<&'a ()> = ::core::marker::PhantomData,
135///         _b: ::core::marker::PhantomData<&'b ()> = ::core::marker::PhantomData
136///     }
137/// }
138/// ```
139///
140/// There're some limitations:
141///
142/// - The inner field must be named as `inner` (e.g. `inner: P`).
143/// - When no default value is specified, the wrapper type will not implement
144///   the `From` trait.
145/// - Does **NOT** automatically apply `repr(transparent)` attribute, since the
146///   macro doesn't know if other fields were zero-sized types (ZST).
147///
148/// ## Notice
149///
150/// - The `wrapper_impl` attribute must be on top of any other attributes.
151/// - Should **NOT** implement `Deref` and `DerefMut` at the same time (when
152///   `DerefMut` is implemented, `Deref` would be implemented, too).
153macro_rules! wrapper {
154    // To filter out the `wrapper_impl` attribute and extract the inner type.
155    (
156        @INTERNEL IMPL
157        #[wrapper_impl(AsRef)]
158        $($tt:tt)*
159    ) => {
160        $crate::wrapper! {
161            @INTERNEL IMPL
162            $($tt)*
163        }
164    };
165    (
166        @INTERNEL IMPL
167        #[wrapper_impl(AsMut)]
168        $($tt:tt)*
169    ) => {
170        $crate::wrapper! {
171            @INTERNEL IMPL
172            $($tt)*
173        }
174    };
175    (
176        @INTERNEL IMPL
177        #[wrapper_impl(Borrow)]
178        $($tt:tt)*
179    ) => {
180        $crate::wrapper! {
181            @INTERNEL IMPL
182            $($tt)*
183        }
184    };
185    (
186        @INTERNEL IMPL
187        #[wrapper_impl(Deref)]
188        $($tt:tt)*
189    ) => {
190        $crate::wrapper! {
191            @INTERNEL IMPL
192            $($tt)*
193        }
194    };
195    (
196        @INTERNEL IMPL
197        #[wrapper_impl(DerefMut)]
198        $($tt:tt)*
199    ) => {
200        $crate::wrapper! {
201            @INTERNEL IMPL
202            $($tt)*
203        }
204    };
205    (
206        @INTERNEL IMPL
207        #[wrapper_impl(From)]
208        $($tt:tt)*
209    ) => {
210        $crate::wrapper! {
211            @INTERNEL IMPL
212            $($tt)*
213        }
214    };
215
216    // The actual implementation of the wrapper type: `pub Name<...>(...)`
217    (
218        @INTERNEL IMPL
219        $(#[$outer:meta])*
220        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty)
221    ) => {
222        $(#[$outer])*
223        #[repr(transparent)]
224        $vis struct $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
225            /// Inner value
226            $inner_vis inner: $inner_ty,
227        }
228
229        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
230            #[inline(always)]
231            #[doc = concat!("Creates a new instance of [`", stringify!($name), "`]")]
232            $inner_vis const fn const_from(inner: $inner_ty) -> Self {
233                Self {
234                    inner,
235                }
236            }
237        }
238    };
239
240    // The actual implementation of the wrapper type: `pub struct Name<...> { ... }`, with field initial value provided, make `const_from` const.
241    (
242        @INTERNEL IMPL
243        $(#[$outer:meta])*
244        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
245            $(#[$field_inner_meta:meta])*
246            $inner_vis:vis inner: $inner_ty:ty
247            $(
248                ,
249                $(#[$field_meta:meta])*
250                $field_vis:vis $field:ident: $field_ty:ty = $field_default: expr
251            )*
252            $(,)?
253        }
254    ) => {
255        $(#[$outer])*
256        $vis struct $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
257            $(#[$field_inner_meta])*
258            $inner_vis inner: $inner_ty,
259            $(
260                $(#[$field_meta])*
261                $field_vis $field: $field_ty
262            ),*
263        }
264
265        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
266            #[inline(always)]
267            #[doc = concat!("Creates a new instance of [`", stringify!($name), "`]")]
268            $inner_vis const fn const_from(inner: $inner_ty) -> Self {
269                Self {
270                    inner,
271                    $(
272                        $field: $field_default,
273                    )*
274                }
275            }
276        }
277    };
278
279    // The actual implementation of the wrapper type with fields: `pub struct Name<...> { ... }`
280    (
281        @INTERNEL IMPL
282        $(#[$outer:meta])*
283        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
284            $(#[$field_inner_meta:meta])*
285            $inner_vis:vis inner: $inner_ty:ty
286            $(
287                ,
288                $(#[$field_meta:meta])*
289                $field_vis:vis $field:ident: $field_ty:ty
290            )*
291            $(,)?
292        }
293    ) => {
294        $(#[$outer])*
295        $vis struct $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
296            $(#[$field_inner_meta])*
297            $inner_vis inner: $inner_ty
298            $(
299                ,
300                $(#[$field_meta])*
301                $field_vis $field: $field_ty
302            )*
303        }
304    };
305
306    // Extract wrapper impl for `AsRef` trait.
307    (
308        @INTERNEL WRAPPER_IMPL
309        #[wrapper_impl(AsRef)]
310        $($tt:tt)*
311    ) => {
312        $crate::wrapper! {
313            @INTERNEL WRAPPER_IMPL_AS_REF
314            $($tt)*
315        }
316
317        $crate::wrapper! {
318            @INTERNEL WRAPPER_IMPL
319            $($tt)*
320        }
321    };
322
323    // Extract wrapper impl for `AsMut` trait.
324    (
325        @INTERNEL WRAPPER_IMPL
326        #[wrapper_impl(AsMut)]
327        $($tt:tt)*
328    ) => {
329        $crate::wrapper! {
330            @INTERNEL WRAPPER_IMPL_AS_MUT
331            $($tt)*
332        }
333
334        $crate::wrapper! {
335            @INTERNEL WRAPPER_IMPL
336            $($tt)*
337        }
338    };
339
340    // Extract wrapper impl for `Borrow` trait.
341    (
342        @INTERNEL WRAPPER_IMPL
343        #[wrapper_impl(Borrow)]
344        $($tt:tt)*
345    ) => {
346        $crate::wrapper! {
347            @INTERNEL WRAPPER_IMPL_BORROW
348            $($tt)*
349        }
350
351        $crate::wrapper! {
352            @INTERNEL WRAPPER_IMPL
353            $($tt)*
354        }
355    };
356
357    // Extract wrapper impl for `DerefMut` trait (and `Deref`).
358    (
359        @INTERNEL WRAPPER_IMPL
360        #[wrapper_impl(DerefMut)]
361        $($tt:tt)*
362    ) => {
363        $crate::wrapper! {
364            @INTERNEL WRAPPER_IMPL_DEREF_MUT
365            $($tt)*
366        }
367
368        $crate::wrapper! {
369            @INTERNEL WRAPPER_IMPL
370            $($tt)*
371        }
372    };
373
374    // Extract wrapper impl for `Deref` trait.
375    (
376        @INTERNEL WRAPPER_IMPL
377        #[wrapper_impl(Deref)]
378        $($tt:tt)*
379    ) => {
380        $crate::wrapper! {
381            @INTERNEL WRAPPER_IMPL_DEREF
382            $($tt)*
383        }
384
385        $crate::wrapper! {
386            @INTERNEL WRAPPER_IMPL
387            $($tt)*
388        }
389    };
390
391    // Extract wrapper impl for `From` trait.
392    (
393        @INTERNEL WRAPPER_IMPL
394        #[wrapper_impl(From)]
395        $($tt:tt)*
396    ) => {
397        $crate::wrapper! {
398            @INTERNEL WRAPPER_IMPL_FROM
399            $($tt)*
400        }
401
402        $crate::wrapper! {
403            @INTERNEL WRAPPER_IMPL
404            $($tt)*
405        }
406    };
407
408    // ================ Impl `AsRef` trait for the wrapper type. ================
409    (
410        @INTERNEL WRAPPER_IMPL_AS_REF
411        $(#[$meta:meta])*
412        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
413        ($inner_vis:vis $inner_ty:ty)
414        $($tt:tt)*
415    ) => {
416        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsRef<$inner_ty> for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
417            fn as_ref(&self) -> &$inner_ty {
418                &self.inner
419            }
420        }
421
422        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
423            /// Returns a reference to the inner value.
424            #[inline(always)]
425            pub const fn as_inner(&self) -> &$inner_ty {
426                &self.inner
427            }
428        }
429    };
430    (
431        @INTERNEL WRAPPER_IMPL_AS_REF
432        $(#[$meta:meta])*
433        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
434            $(#[$field_inner_meta:meta])*
435            $inner_vis:vis inner: $inner_ty:ty
436            $(
437                ,
438                $(#[$field_meta:meta])*
439                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
440            )*
441            $(,)?
442        }
443    ) => {
444        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsRef<$inner_ty> for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
445            fn as_ref(&self) -> &$inner_ty {
446                &self.inner
447            }
448        }
449
450        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
451            /// Returns a reference to the inner value.
452            #[inline(always)]
453            pub const fn as_inner(&self) -> &$inner_ty {
454                &self.inner
455            }
456        }
457    };
458    // ================ Impl `AsRef` trait for the wrapper type. ================
459
460
461    // ================ Impl `AsMut` trait for the wrapper type. ================
462    (
463        @INTERNEL WRAPPER_IMPL_AS_MUT
464        $(#[$meta:meta])*
465        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
466        ($inner_vis:vis $inner_ty:ty)
467        $($tt:tt)*
468    ) => {
469        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsMut<$inner_ty> for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
470            fn as_mut(&mut self) -> &mut $inner_ty {
471                &mut self.inner
472            }
473        }
474
475        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
476            /// Returns a reference to the inner value.
477            #[inline(always)]
478            pub const fn as_inner_mut(&mut self) -> &mut $inner_ty {
479                &mut self.inner
480            }
481        }
482    };
483    (
484        @INTERNEL WRAPPER_IMPL_AS_MUT
485        $(#[$meta:meta])*
486        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
487            $(#[$field_inner_meta:meta])*
488            $inner_vis:vis inner: $inner_ty:ty
489            $(
490                ,
491                $(#[$field_meta:meta])*
492                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
493            )*
494            $(,)?
495        }
496    ) => {
497        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsMut<$inner_ty> for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
498            fn as_mut(&mut self) -> &mut $inner_ty {
499                &mut self.inner
500            }
501        }
502
503        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
504            /// Returns a reference to the inner value.
505            #[cfg_attr(feature = "const-mut-method", rustversion::attr(since(1.83), const))]
506            #[inline(always)]
507            pub fn as_inner_mut(&mut self) -> &mut $inner_ty {
508                &mut self.inner
509            }
510        }
511    };
512    // ================ Impl `AsMut` trait for the wrapper type. ================
513
514    // ================ Impl `Borrow` trait for the wrapper type. ================
515    (
516        @INTERNEL WRAPPER_IMPL_BORROW
517        $(#[$meta:meta])*
518        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
519        ($inner_vis:vis $inner_ty:ty)
520        $($tt:tt)*
521    ) => {
522        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::borrow::Borrow<$inner_ty> for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
523            fn borrow(&self) -> &$inner_ty {
524                &self.inner
525            }
526        }
527    };
528    (
529        @INTERNEL WRAPPER_IMPL_BORROW
530        $(#[$meta:meta])*
531        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
532            $(#[$field_inner_meta:meta])*
533            $inner_vis:vis inner: $inner_ty:ty
534            $(
535                ,
536                $(#[$field_meta:meta])*
537                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
538            )*
539            $(,)?
540        }
541    ) => {
542        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::borrow::Borrow<$inner_ty> for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
543            fn borrow(&self) -> &$inner_ty {
544                &self.inner
545            }
546        }
547    };
548    // ================ Impl `Borrow` trait for the wrapper type. ================
549
550    // ================ Impl `Deref` and `DerefMut` traits for the wrapper type. ================
551    (
552        @INTERNEL WRAPPER_IMPL_DEREF_MUT
553        $(#[$meta:meta])*
554        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
555        ($inner_vis:vis $inner_ty:ty)
556        $($tt:tt)*
557    ) => {
558        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::Deref for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
559            type Target = $inner_ty;
560
561            fn deref(&self) -> &Self::Target {
562                &self.inner
563            }
564        }
565
566        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::DerefMut for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
567            fn deref_mut(&mut self) -> &mut Self::Target {
568                &mut self.inner
569            }
570        }
571    };
572    (
573        @INTERNEL WRAPPER_IMPL_DEREF_MUT
574        $(#[$meta:meta])*
575        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
576            $(#[$field_inner_meta:meta])*
577            $inner_vis:vis inner: $inner_ty:ty
578            $(
579                ,
580                $(#[$field_meta:meta])*
581                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
582            )*
583            $(,)?
584        }
585    ) => {
586        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::Deref for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
587            type Target = $inner_ty;
588
589            fn deref(&self) -> &Self::Target {
590                &self.inner
591            }
592        }
593
594        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::DerefMut for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
595            fn deref_mut(&mut self) -> &mut Self::Target {
596                &mut self.inner
597            }
598        }
599    };
600    // ================ Impl `Deref` and `DerefMut` traits for the wrapper type. ================
601
602    // ================ Impl `Deref` trait for the wrapper type. ================
603    (
604        @INTERNEL WRAPPER_IMPL_DEREF
605        $(#[$meta:meta])*
606        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
607        ($inner_vis:vis $inner_ty:ty)
608        $($tt:tt)*
609    ) => {
610        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::Deref for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
611            type Target = $inner_ty;
612
613            fn deref(&self) -> &Self::Target {
614                &self.inner
615            }
616        }
617    };
618    (
619        @INTERNEL WRAPPER_IMPL_DEREF
620        $(#[$meta:meta])*
621        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
622            $(#[$field_inner_meta:meta])*
623            $inner_vis:vis inner: $inner_ty:ty
624            $(
625                ,
626                $(#[$field_meta:meta])*
627                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
628            )*
629            $(,)?
630        }
631    ) => {
632        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::Deref for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
633            type Target = $inner_ty;
634
635            fn deref(&self) -> &Self::Target {
636                &self.inner
637            }
638        }
639    };
640    // ================ Impl `Deref` trait for the wrapper type. ================
641
642    // ================ Impl `From` trait for the wrapper type. ================
643    (
644        @INTERNEL WRAPPER_IMPL_FROM
645        $(#[$meta:meta])*
646        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
647        ($inner_vis:vis $inner_ty:ty)
648        $($tt:tt)*
649    ) => {
650        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::From<$inner_ty> for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
651            fn from(inner: $inner_ty) -> Self {
652                Self::const_from(inner)
653            }
654        }
655
656        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
657            /// Creates a new instance of the wrapper type from the inner value.
658            #[allow(unreachable_pub)]
659            #[inline(always)]
660            pub const fn from(inner: $inner_ty) -> Self {
661                Self::const_from(inner)
662            }
663        }
664    };
665    (
666        @INTERNEL WRAPPER_IMPL_FROM
667        $(#[$meta:meta])*
668        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
669            $(#[$field_inner_meta:meta])*
670            $inner_vis:vis inner: $inner_ty:ty
671            $(
672                ,
673                $(#[$field_meta:meta])*
674                $field_vis:vis $field:ident: $field_ty:ty = $field_default:expr
675            )*
676            $(,)?
677        }
678    ) => {
679        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::From<$inner_ty> for $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
680            fn from(inner: $inner_ty) -> Self {
681                Self::const_from(inner)
682            }
683        }
684
685        impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt$(:$clt$(+$dlt)*)?),+>)? {
686            /// Creates a new instance of the wrapper type from the inner value.
687            #[allow(unreachable_pub)]
688            #[inline(always)]
689            pub const fn from(inner: $inner_ty) -> Self {
690                Self::const_from(inner)
691            }
692        }
693    };
694    (@INTERNEL WRAPPER_IMPL_FROM $($tt:tt)*) => {};
695    // ================ Impl `From` trait for the wrapper type. ================
696
697    // No other wrapper_impl meta
698    (@INTERNEL WRAPPER_IMPL $($tt:tt)*) => {};
699
700    // Catch-all for invalid usage of the macro.
701    (@INTERNEL $($tt:tt)*) => {
702        compile_error!(
703            "Invalid usage of `wrapper!` macro. @INTERNEL \
704            Please refer to the documentation for the correct syntax."
705        );
706    };
707
708    // Core macro for the wrapper type.
709    ($($tt:tt)*) => {
710        $crate::wrapper!(@INTERNEL IMPL $($tt)*);
711        $crate::wrapper!(@INTERNEL WRAPPER_IMPL $($tt)*);
712    };
713}
714
715#[doc(hidden)]
716pub fn _assert_impl_debug<T>()
717where
718    T: ::core::fmt::Debug,
719{
720}
721
722#[doc(hidden)]
723pub fn _assert_impl_as_ref<T, U>()
724where
725    T: ::core::convert::AsRef<U>,
726{
727}
728
729#[doc(hidden)]
730pub fn _assert_impl_as_mut<T, U>()
731where
732    T: ::core::convert::AsMut<U>,
733{
734}
735
736#[doc(hidden)]
737pub fn _assert_impl_borrow<T, U>()
738where
739    T: ::core::borrow::Borrow<U>,
740{
741}
742
743#[doc(hidden)]
744pub fn _assert_impl_deref<T, U>()
745where
746    T: ::core::ops::Deref<Target = U>,
747{
748}
749
750#[doc(hidden)]
751pub fn _assert_impl_deref_mut<T, U>()
752where
753    T: ::core::ops::DerefMut<Target = U>,
754{
755}
756
757#[doc(hidden)]
758pub fn _assert_impl_from<T, U>()
759where
760    T: ::core::convert::From<U>,
761{
762}
763
764// #[cfg(any(test, doctest))]
765mod simple {
766    #![allow(unused)]
767    #![allow(unreachable_pub)]
768    #![allow(dead_code)]
769    #![allow(non_snake_case)]
770
771    use ::alloc::string::String;
772
773    use super::*;
774
775    wrapper! {
776        #[wrapper_impl(AsRef)]
777        pub TestWrapperImplAsRef(String)
778    }
779
780    fn assert_impls_TestWrapperImplAsRef() {
781        _assert_impl_as_ref::<TestWrapperImplAsRef, _>();
782    }
783
784    #[test]
785    fn assert_size_eq() {
786        use core::mem::size_of;
787
788        assert_eq!(size_of::<TestWrapperImplAsRef>(), size_of::<String>());
789    }
790
791    wrapper! {
792        #[wrapper_impl(AsRef)]
793        #[derive(Debug)]
794        pub TestWrapperImplAsRefMixed(String)
795    }
796
797    fn assert_impls_TestWrapperImplAsRefMixed() {
798        _assert_impl_debug::<TestWrapperImplAsRefMixed>();
799        _assert_impl_as_ref::<TestWrapperImplAsRefMixed, _>();
800    }
801
802    wrapper! {
803        #[wrapper_impl(Borrow)]
804        pub TestWrapperImplBorrow(String)
805    }
806
807    fn assert_impls_TestWrapperImplBorrow() {
808        _assert_impl_borrow::<TestWrapperImplBorrow, String>();
809    }
810
811    wrapper! {
812        #[wrapper_impl(Borrow)]
813        #[derive(Debug)]
814        pub TestWrapperImplBorrowMixed(String)
815    }
816
817    fn assert_impls_TestWrapperImplBorrowMixed() {
818        _assert_impl_debug::<TestWrapperImplBorrowMixed>();
819        _assert_impl_borrow::<TestWrapperImplBorrowMixed, String>();
820    }
821
822    wrapper! {
823        #[wrapper_impl(Deref)]
824        pub TestWrapperImplDeref(String)
825    }
826
827    fn assert_impls_TestWrapperImplDeref() {
828        _assert_impl_deref::<TestWrapperImplDeref, _>();
829    }
830
831    wrapper! {
832        #[wrapper_impl(Deref)]
833        #[derive(Debug)]
834        pub TestWrapperImplDerefMixed(String)
835    }
836
837    fn assert_impls_TestWrapperImplDerefMixed() {
838        _assert_impl_debug::<TestWrapperImplDerefMixed>();
839        _assert_impl_deref::<TestWrapperImplDerefMixed, _>();
840    }
841
842    wrapper! {
843        #[wrapper_impl(DerefMut)]
844        pub TestWrapperImplDerefMut(String)
845    }
846
847    fn assert_impls_TestWrapperImplDerefMut() {
848        _assert_impl_deref_mut::<TestWrapperImplDerefMut, _>();
849    }
850
851    wrapper! {
852        #[wrapper_impl(DerefMut)]
853        #[derive(Debug)]
854        pub TestWrapperImplDerefMutMixed(String)
855    }
856
857    fn assert_impls_TestWrapperImplDerefMutMixed() {
858        _assert_impl_debug::<TestWrapperImplDerefMutMixed>();
859        _assert_impl_deref_mut::<TestWrapperImplDerefMutMixed, _>();
860    }
861
862    wrapper! {
863        #[wrapper_impl(From)]
864        pub TestWrapperImplFrom(String)
865    }
866
867    fn assert_impls_TestWrapperImplFrom() {
868        _assert_impl_from::<TestWrapperImplFrom, String>();
869    }
870
871    wrapper! {
872        #[wrapper_impl(From)]
873        #[derive(Debug)]
874        pub TestWrapperImplFromMixed(String)
875    }
876
877    fn assert_impls_TestWrapperImplFromMixed() {
878        _assert_impl_debug::<TestWrapperImplFromMixed>();
879        _assert_impl_from::<TestWrapperImplFromMixed, String>();
880    }
881
882    // Test multiple
883    wrapper! {
884        #[wrapper_impl(Deref)]
885        #[wrapper_impl(From)]
886        #[derive(Debug)]
887        pub TestWrapperImplFromDeref(String)
888    }
889
890    fn assert_impls_TestWrapperImplFromDeref() {
891        _assert_impl_debug::<TestWrapperImplFromDeref>();
892        _assert_impl_deref::<TestWrapperImplFromDeref, _>();
893        _assert_impl_from::<TestWrapperImplFromDeref, String>();
894    }
895
896    // Test multiple with lifetimes
897    wrapper! {
898        #[wrapper_impl(Deref)]
899        #[wrapper_impl(From)]
900        #[derive(Debug)]
901        pub TestWrapperImplFromDerefMixed<'a, P>(pub(crate) &'a P)
902    }
903
904    fn assert_impls_TestWrapperImplFromDerefMixed<P: core::fmt::Debug>() {
905        _assert_impl_debug::<TestWrapperImplFromDerefMixed<'_, P>>();
906        _assert_impl_deref::<TestWrapperImplFromDerefMixed<'_, P>, _>();
907        _assert_impl_from::<TestWrapperImplFromDerefMixed<'_, P>, &P>();
908    }
909}
910
911// #[cfg(any(test, doctest))]
912mod complex {
913    #![allow(unused)]
914    #![allow(unreachable_pub)]
915    #![allow(dead_code)]
916    #![allow(non_snake_case)]
917
918    use alloc::string::String;
919
920    use super::*;
921
922    wrapper! {
923        pub struct TestWrapperEmpty<'a, 'b> {
924            inner: String,
925            _a: ::core::marker::PhantomData<&'a ()>,
926            _b: ::core::marker::PhantomData<&'b ()>
927        }
928    }
929
930    wrapper! {
931        pub struct TestWrapperEmptyWithTailing<'a, 'b> {
932            inner: String,
933            _a: ::core::marker::PhantomData<&'a ()>,
934            _b: ::core::marker::PhantomData<&'b ()>,
935        }
936    }
937
938    wrapper! {
939        pub struct TestWrapperEmptyWithDefault<'a, 'b> {
940            inner: String,
941            _a: ::core::marker::PhantomData<&'a ()> = ::core::marker::PhantomData,
942            _b: ::core::marker::PhantomData<&'b ()> = ::core::marker::PhantomData
943        }
944    }
945
946    wrapper! {
947        pub struct TestWrapperEmptyWithDefaultWithTailing<'a, 'b> {
948            inner: String,
949            _a: ::core::marker::PhantomData<&'a ()> = ::core::marker::PhantomData,
950            _b: ::core::marker::PhantomData<&'b ()> = ::core::marker::PhantomData,
951        }
952    }
953
954    wrapper! {
955        #[wrapper_impl(AsMut)]
956        #[wrapper_impl(AsRef)]
957        #[wrapper_impl(Borrow)]
958        #[wrapper_impl(DerefMut)]
959        #[wrapper_impl(From)]
960        #[derive(Debug)]
961        #[repr(transparent)]
962        pub struct TestWrapperComplexConstFromInner<'a, 'b> {
963            inner: String,
964            _a: ::core::marker::PhantomData<&'a ()> = ::core::marker::PhantomData,
965            _b: ::core::marker::PhantomData<&'b ()> = ::core::marker::PhantomData
966        }
967    }
968
969    #[test]
970    fn assert_impls_TestWrapperComplexConstFromInner() {
971        _assert_impl_debug::<TestWrapperComplexConstFromInner<'_, '_>>();
972        _assert_impl_as_ref::<TestWrapperComplexConstFromInner<'_, '_>, _>();
973        _assert_impl_as_mut::<TestWrapperComplexConstFromInner<'_, '_>, _>();
974        _assert_impl_borrow::<TestWrapperComplexConstFromInner<'_, '_>, String>();
975        _assert_impl_deref_mut::<TestWrapperComplexConstFromInner<'_, '_>, _>();
976        _assert_impl_from::<TestWrapperComplexConstFromInner<'_, '_>, String>();
977
978        assert_eq!(
979            core::mem::size_of::<TestWrapperComplexConstFromInner<'_, '_>>(),
980            core::mem::size_of::<String>()
981        );
982    }
983
984    wrapper! {
985        #[wrapper_impl(AsMut)]
986        #[wrapper_impl(AsRef)]
987        #[wrapper_impl(Borrow)]
988        #[wrapper_impl(DerefMut)]
989        #[wrapper_impl(From)]
990        #[repr(transparent)]
991        #[derive(Debug)]
992        pub struct TestWrapperComplex<'a, 'b> {
993            inner: String,
994            _a: ::core::marker::PhantomData<&'a ()>,
995            _b: ::core::marker::PhantomData<&'b ()>
996        }
997    }
998
999    #[test]
1000    fn assert_impls_TestWrapperComplex() {
1001        _assert_impl_debug::<TestWrapperComplex<'_, '_>>();
1002        _assert_impl_as_ref::<TestWrapperComplex<'_, '_>, _>();
1003        _assert_impl_as_mut::<TestWrapperComplex<'_, '_>, _>();
1004        _assert_impl_borrow::<TestWrapperComplex<'_, '_>, String>();
1005        _assert_impl_deref_mut::<TestWrapperComplex<'_, '_>, _>();
1006        // _assert_impl_from::<TestWrapperComplex<'_, '_>, String>();
1007
1008        assert_eq!(
1009            core::mem::size_of::<TestWrapperComplex<'_, '_>>(),
1010            core::mem::size_of::<String>()
1011        );
1012    }
1013}