Macro wrapper

Source
macro_rules! wrapper {
    (
        @INTERNEL IMPL
        #[wrapper_impl(AsRef)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL IMPL
        #[wrapper_impl(AsMut)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL IMPL
        #[wrapper_impl(Borrow)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL IMPL
        #[wrapper_impl(Deref)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL IMPL
        #[wrapper_impl(DerefMut)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL IMPL
        #[wrapper_impl(From)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL IMPL
        $(#[$outer:meta])*
        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty)
    ) => { ... };
    (
        @INTERNEL IMPL
        $(#[$outer:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis inner: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty = $field_default: expr
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNEL IMPL
        $(#[$outer:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis inner: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL
        #[wrapper_impl(AsRef)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL
        #[wrapper_impl(AsMut)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL
        #[wrapper_impl(Borrow)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL
        #[wrapper_impl(DerefMut)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL
        #[wrapper_impl(Deref)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL
        #[wrapper_impl(From)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_AS_REF
        $(#[$meta:meta])*
        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
        ($inner_vis:vis $inner_ty:ty)
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_AS_REF
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis inner: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_AS_MUT
        $(#[$meta:meta])*
        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
        ($inner_vis:vis $inner_ty:ty)
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_AS_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis inner: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_BORROW
        $(#[$meta:meta])*
        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
        ($inner_vis:vis $inner_ty:ty)
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_BORROW
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis inner: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_DEREF_MUT
        $(#[$meta:meta])*
        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
        ($inner_vis:vis $inner_ty:ty)
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_DEREF_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis inner: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_DEREF
        $(#[$meta:meta])*
        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
        ($inner_vis:vis $inner_ty:ty)
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_DEREF
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis inner: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_FROM
        $(#[$meta:meta])*
        $vis:vis $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
        ($inner_vis:vis $inner_ty:ty)
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNEL WRAPPER_IMPL_FROM
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis inner: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty = $field_default:expr
            )*
            $(,)?
        }
    ) => { ... };
    (@INTERNEL WRAPPER_IMPL_FROM $($tt:tt)*) => { ... };
    (@INTERNEL WRAPPER_IMPL $($tt:tt)*) => { ... };
    (@INTERNEL $($tt:tt)*) => { ... };
    ($($tt:tt)*) => { ... };
}
Expand description

Helper macro for creating a wrapper over any type (new-type idom).

§Usage: basic

wrapper! {
    #[wrapper_impl(AsRef)]
    #[wrapper_impl(AsMut)]
    #[wrapper_impl(Borrow)]
    // #[wrapper_impl(Deref)]
    #[wrapper_impl(DerefMut)]
    #[wrapper_impl(From)]
    #[derive(Debug, Clone, Copy)]
    pub ExampleWrapper<'a, P>(pub(crate) &'a P)
}

Generates const accessor methods for wrapper types implementing AsRef and AsMut traits.

For types implementing AsRef, this creates a const method as_inner that returns a reference to the wrapped value. For types implementing AsMut, this creates a const method as_inner_mut that returns a mutable reference to the wrapped value.

Additionally generates a const constructor method const_from for the wrapper type, using the same visibility as the inner field. When the From trait is implemented, also generates a public const method from.

§Usage: advanced

You can also create a wrapper type with a struct with multiple fields, especially when some lifetime markers or generics markers are needed.

wrapper! {
    #[wrapper_impl(AsMut)]
    #[wrapper_impl(AsRef)]
    #[wrapper_impl(Borrow)]
    #[wrapper_impl(DerefMut)]
    #[wrapper_impl(From)]
    #[derive(Debug)]
    #[repr(transparent)]
    pub struct ExampleWrapperComplex<'a, 'b, P> {
        inner: P,
        _a: ::core::marker::PhantomData<&'a ()> = ::core::marker::PhantomData,
        _b: ::core::marker::PhantomData<&'b ()> = ::core::marker::PhantomData
    }
}

There’re some limitations:

  • The inner field must be named as inner (e.g. inner: P).
  • When no default value is specified, the wrapper type will not implement the From trait.
  • Does NOT automatically apply repr(transparent) attribute, since the macro doesn’t know if other fields were zero-sized types (ZST).

§Notice

  • The wrapper_impl attribute must be on top of any other attributes.
  • Should NOT implement Deref and DerefMut at the same time (when DerefMut is implemented, Deref would be implemented, too).