wrapper

Macro wrapper 

Source
macro_rules! wrapper {
    (
        @INTERNAL IMPL
        #[wrapper_impl(AsRef $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[wrapper_impl(AsMut $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[wrapper_impl(ConstAsMut $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[wrapper_impl(Borrow $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[wrapper_impl(BorrowMut $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[wrapper_impl(Deref $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[wrapper_impl(DerefMut $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[wrapper_impl(From)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[wrapper_impl(Debug)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[wrapper_impl(DebugName)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[wrapper_impl(Display)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL IMPL
        #[repr(align(cache))]
        $(#[$outer:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL IMPL
        $(#[$outer:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL IMPL
        #[repr(align(cache))]
        $(#[$outer:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty = $field_default: expr
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL IMPL
        $(#[$outer:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty = $field_default: expr
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL IMPL
        #[repr(align(cache))]
        $(#[$outer:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL IMPL
        $(#[$outer:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(AsRef $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(AsMut $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(ConstAsMut $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(Borrow $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(BorrowMut $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(Debug)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(DebugName)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(Display)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(Deref $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(DerefMut $(<$target:ty>)? )]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL
        #[wrapper_impl(From)]
        $($tt:tt)*
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_AS_REF <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_AS_REF <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_AS_REF
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_AS_REF
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_AS_MUT <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_AS_MUT <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_AS_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_AS_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_CONST_AS_MUT <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_CONST_AS_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_CONST_AS_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_CONST_AS_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_BORROW <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_BORROW <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_BORROW
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_BORROW
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_BORROW_MUT <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_BORROW_MUT <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_BORROW_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_BORROW_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEBUG
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEBUG
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEBUG_NAME
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEBUG_NAME
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DISPLAY
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DISPLAY
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEREF <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEREF <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEREF
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEREF
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEREF_MUT <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEREF_MUT <$target:ty>
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEREF_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_DEREF_MUT
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_FROM
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? ($inner_vis:vis $inner_ty:ty);
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_FROM
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty = $field_default:expr
            )*
            $(,)?
        }
    ) => { ... };
    (
        @INTERNAL WRAPPER_IMPL_FROM
        $(#[$meta:meta])*
        $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?$(=$default:tt)?),+>)? {
            $(#[$field_inner_meta:meta])*
            $inner_vis:vis $inner:ident: $inner_ty:ty
            $(
                ,
                $(#[$field_meta:meta])*
                $field_vis:vis $field:ident: $field_ty:ty
            )*
            $(,)?
        }
    ) => { ... };
    (@INTERNAL WRAPPER_IMPL $($tt:tt)*) => { ... };
    (@INTERNAL $($tt:tt)*) => { ... };
    ($($tt:tt)*) => { ... };
}
Expand description

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

§Usage

It’s worth noting that wrapper! { ... } is almost equivalent to wrapper!( ... ); but lacking cargo-fmt support. We recommend using the latter.

§Usage: basic

wrapper_lite::wrapper!(
    #[wrapper_impl(AsRef)]
    #[wrapper_impl(AsMut)]
    // #[wrapper_impl(Borrow)]
    #[wrapper_impl(BorrowMut)]
    // #[wrapper_impl(Deref)]
    #[wrapper_impl(DerefMut)]
    #[wrapper_impl(From)]
    #[derive(Debug, Clone, Copy)]
    pub struct 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, sharing the same visibility as the inner field.

Additionally generates a const constructor method from_inner for the wrapper type when possible, also sharing 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 too complex, or you need some custom fields.

Here’s an complex example:

use core::fmt::Debug;
use core::marker::PhantomData;

wrapper_lite::wrapper!(
    #[wrapper_impl(AsMut)]
    #[wrapper_impl(AsRef)]
    // #[wrapper_impl(Borrow)]
    #[wrapper_impl(BorrowMut)]
    // #[wrapper_impl(Deref)]
    #[wrapper_impl(DerefMut)]
    // #[wrapper_impl(From)]
    #[wrapper_impl(Debug)]
    #[derive(Clone, Copy, PartialEq, Eq)]
    #[repr(transparent)]
    pub struct ExampleWrapperComplex<'a, 'b: 'a, P: Debug = String> {
        inner: P,
        _a: PhantomData<&'a ()>,
        _b: PhantomData<&'b ()>,
    }
);

There’re some known limitations:

  • The inner field must be the first one declared in the struct (the name does not matter)

  • When there’s no default value specified, we cannot implement the From trait for the wrapper type. You may specify a default value like this:

    wrapper_lite::wrapper!(
        #[wrapper_impl(From)]
        pub struct ExampleWrapperComplexWithDefault<P> {
            inner: P,
           _marker: u8 = 0,
        }
    );

    However, the non-Rust syntax will make cargo-fmt upset, and you can just implement the From trait by yourself.

  • For trait bounds on generics parameters, you have to import the traits and cannot specify a path (e.g., T: ::core::fmt::Debug) due to the limitation of procedural macros.

  • where clauses are not supported yet.

§Special usages

§Debug and DebugName

We offer Debug and DebugName attributes to control how the wrapper type is printed when using the Debug trait, instead of #[derive(Debug)].

  • #[wrapper_impl(Debug)]: transparently implements the Debug trait if the inner type implements it. The debug output is the same as the inner one.
  • #[wrapper_impl(DebugName)]: implements the Debug trait, but only prints the name of the wrapper type.
wrapper_lite::wrapper!(
    #[wrapper_impl(Debug)]
    #[derive(Clone, Copy)]
    pub struct ExampleWrapperDebug<'a, P>(&'a P);
);

wrapper_lite::wrapper!(
    #[wrapper_impl(DebugName)]
    #[derive(Clone, Copy)]
    pub struct ExampleWrapperDebugName<'a, P>(&'a P);
);

let data = "Hello".to_string();

// Here we transparently print the debug output of the inner type.
assert_eq!(
    format!("{:?}", ExampleWrapperDebug { inner: &data }),
    "\"Hello\""
);
// Here we only print the name of the wrapper type.
assert_eq!(
    format!("{:?}", ExampleWrapperDebugName { inner: &data }),
    "ExampleWrapperDebugName"
);

§Display

Like Debug.

wrapper_lite::wrapper!(
    #[wrapper_impl(Display)]
    #[derive(Clone, Copy)]
    pub struct ExampleWrapperDisplay<'a, P>(&'a P);
);

let data = "Hello".to_string();

// Here we transparently print the debug output of the inner type.
assert_eq!(
    format!("{}", ExampleWrapperDisplay { inner: &data }),
    "Hello"
);

§ConstAsMut

Like AsMut, but instead generates a const version of as_inner_mut method (stable since Rust 1.83.0+).

wrapper_lite::wrapper!(
    #[wrapper_impl(ConstAsMut)]
    #[derive(Debug, Clone, Copy)]
    pub struct ExampleWrapper<P>(pub(crate) P);
);

const fn const_fn_example<P>(w: &mut ExampleWrapper<P>) -> &mut P {
    w.as_inner_mut()
}

§AsRef<T>, AsMut<T>, Borrow<T>, BorrowMut<T>, Deref<T>, DerefMut<T>

These attributes allow you to specify a target type T for the respective traits (experimental). This is done by auto-dereferencing the inner type to get a reference to T.

wrapper_lite::wrapper!(
    #[wrapper_impl(AsRef<[u8]>)]
    #[wrapper_impl(AsMut<[u8]>)]
    // #[wrapper_impl(Borrow<[u8]>)]
    #[wrapper_impl(BorrowMut<[u8]>)]
    // #[wrapper_impl(Deref<[u8]>)]
    #[wrapper_impl(DerefMut<[u8]>)]
    pub struct ExampleWrapper(pub(crate) Vec<u8>);
);

§repr(align(cache))

You can use #[repr(align(cache))] to pad and align the wrapper type to the cache line size. This is useful for performance optimization in certain scenarios.

wrapper_lite::wrapper!(
    #[wrapper_impl(From)]
    #[repr(align(cache))]
    /// Example doc
    pub struct ExampleWrapperCachePadded(u64);
);
#[cfg(target_arch = "x86_64")]
assert_eq!(core::mem::align_of::<ExampleWrapperCachePadded>(), 128);

Credits: https://docs.rs/crossbeam/latest/crossbeam/utils/struct.CachePadded.html.

Notes that repr(align(cache)) must be placed after other #[wrapper_impl(...)] attributes and before any other attributes, including docs.

§Notes

  • The wrapper_impl attribute must be on top of any other attributes.

  • For BorrowMut and DerefMut, the macro will automatically implement the corresponding Borrow and Deref traits, so the following two examples will fail to compile:

    wrapper_lite::wrapper!(
        #[wrapper_impl(Borrow)]
        #[wrapper_impl(BorrowMut)]
        pub struct ExampleWrapper<P>(pub(crate) P);
    );
    wrapper_lite::wrapper!(
        #[wrapper_impl(Deref)]
        #[wrapper_impl(DerefMut)]
        pub struct ExampleWrapper<P>(pub(crate) P);
    );