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
$(#[$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 $(<$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(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)*)?),+>)? ($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)*)?),+>)? {
$(#[$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_REF
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt: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)*)?),+>)? {
$(#[$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 <$target:ty>
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt: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)*)?),+>)? {
$(#[$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);
) => { ... };
(
@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 <$target:ty>
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt: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)*)?),+>)? {
$(#[$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);
) => { ... };
(
@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 <$target:ty>
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt: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)*)?),+>)? {
$(#[$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);
) => { ... };
(
@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 <$target:ty>
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt: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)*)?),+>)? {
$(#[$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);
) => { ... };
(
@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);
) => { ... };
(
@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);
) => { ... };
(
@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 <$target:ty>
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt: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)*)?),+>)? {
$(#[$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);
) => { ... };
(
@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_DEREF_MUT <$target:ty>
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt: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)*)?),+>)? {
$(#[$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);
) => { ... };
(
@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_FROM
$(#[$meta:meta])*
$vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
) => { ... };
(
@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
$(#[$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
)*
$(,)?
}
) => { ... };
(@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 ()>,
}
);
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 ExampleWrapperComplexWithDefault<'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. - When there’s no default value specified, we cannot implement the
Fromtrait for the wrapper type. - The macro does not know if other fields were zero-sized types (ZST), hence
we will not automatically apply
repr(transparent)attribute.
§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 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()
}§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>);
);§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); );