macro_rules! wrapper {
(
@INTERNAL IMPL
#[wrapper_impl(AsRef)]
$($tt:tt)*
) => { ... };
(
@INTERNAL IMPL
#[wrapper_impl(AsMut)]
$($tt:tt)*
) => { ... };
(
@INTERNAL IMPL
#[wrapper_impl(ConstAsMut)]
$($tt:tt)*
) => { ... };
(
@INTERNAL IMPL
#[wrapper_impl(Borrow)]
$($tt:tt)*
) => { ... };
(
@INTERNAL IMPL
#[wrapper_impl(BorrowMut)]
$($tt:tt)*
) => { ... };
(
@INTERNAL IMPL
#[wrapper_impl(Deref)]
$($tt:tt)*
) => { ... };
(
@INTERNAL IMPL
#[wrapper_impl(DerefMut)]
$($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
$(#[$outer:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty) $(;)?
) => { ... };
(
@INTERNAL 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
)*
$(,)?
}
) => { ... };
(
@INTERNAL 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
)*
$(,)?
}
) => { ... };
(
@INTERNAL WRAPPER_IMPL
#[wrapper_impl(AsRef)]
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL
#[wrapper_impl(AsMut)]
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL
#[wrapper_impl(ConstAsMut)]
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL
#[wrapper_impl(Borrow)]
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL
#[wrapper_impl(BorrowMut)]
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL
#[wrapper_impl(Debug)]
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL
#[wrapper_impl(DebugName)]
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL
#[wrapper_impl(DerefMut)]
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL
#[wrapper_impl(Deref)]
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL
#[wrapper_impl(From)]
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL_AS_REF
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)?
($inner_vis:vis $inner_ty:ty)
$($tt:tt)*
) => { ... };
(
@INTERNAL 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)?
)*
$(,)?
}
) => { ... };
(
@INTERNAL WRAPPER_IMPL_AS_MUT
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? $(;)?
($inner_vis:vis $inner_ty:ty)
$($tt:tt)*
) => { ... };
(
@INTERNAL 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)?
)*
$(,)?
}
) => { ... };
(
@INTERNAL WRAPPER_IMPL_CONST_AS_MUT
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? $(;)?
($inner_vis:vis $inner_ty:ty)
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL_CONST_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)?
)*
$(,)?
}
) => { ... };
(
@INTERNAL WRAPPER_IMPL_BORROW
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? $(;)?
($inner_vis:vis $inner_ty:ty)
$($tt:tt)*
) => { ... };
(
@INTERNAL 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)?
)*
$(,)?
}
) => { ... };
(
@INTERNAL WRAPPER_IMPL_BORROW_MUT
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? $(;)?
($inner_vis:vis $inner_ty:ty)
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL_BORROW_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)?
)*
$(,)?
}
) => { ... };
(
@INTERNAL WRAPPER_IMPL_DEBUG
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? $(;)?
($inner_vis:vis $inner_ty:ty)
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL_DEBUG
$(#[$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)?
)*
$(,)?
}
) => { ... };
(
@INTERNAL WRAPPER_IMPL_DEBUG_NAME
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? $(;)?
($inner_vis:vis $inner_ty:ty)
$($tt:tt)*
) => { ... };
(
@INTERNAL WRAPPER_IMPL_DEBUG_NAME
$(#[$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)?
)*
$(,)?
}
) => { ... };
(
@INTERNAL WRAPPER_IMPL_DEREF_MUT
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? $(;)?
($inner_vis:vis $inner_ty:ty)
$($tt:tt)*
) => { ... };
(
@INTERNAL 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)?
)*
$(,)?
}
) => { ... };
(
@INTERNAL WRAPPER_IMPL_DEREF
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? $(;)?
($inner_vis:vis $inner_ty:ty)
$($tt:tt)*
) => { ... };
(
@INTERNAL 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)?
)*
$(,)?
}
) => { ... };
(
@INTERNAL WRAPPER_IMPL_FROM
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? $(;)?
($inner_vis:vis $inner_ty:ty)
$($tt:tt)*
) => { ... };
(
@INTERNAL 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
)*
$(,)?
}
) => { ... };
(@INTERNAL WRAPPER_IMPL_FROM $($tt:tt)*) => { ... };
(@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.
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 too complex, or you need some custom fields.
Here’s an complex example:
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, P> {
inner: P,
_a: ::core::marker::PhantomData<&'a ()>,
_b: ::core::marker::PhantomData<&'b ()>,
}
);There’re some limitations:
- The inner field must be named as
inner. - When no default value is specified, the wrapper type will not implement
the
Fromtrait. Will also not generate theconst_frommethod. - Does not automatically apply
repr(transparent)attribute, since the macro doesn’t know if other fields were zero-sized types (ZST).
§Special attributes
§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 theDebugtrait if the inner type implements it. The debug output is the same as the inner one.#[wrapper_impl(DebugName)]: implements theDebugtrait, 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"
);§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()
}§Notes
-
The
wrapper_implattribute must be on top of any other attributes. -
For
BorrowMutandDerefMut, the macro will automatically implement the correspondingBorrowandDereftraits, 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); );