Skip to content

Instantly share code, notes, and snippets.

@nberlette
Last active November 13, 2024 00:35
Show Gist options
  • Save nberlette/125d5337a175db38111acb519b181e23 to your computer and use it in GitHub Desktop.
Save nberlette/125d5337a175db38111acb519b181e23 to your computer and use it in GitHub Desktop.
[rust macro] impl_wrapper_with_trait
#[macro_export]
macro_rules! impl_wrapper_with_trait {
// Match multiple wrapper types with external type and default implementation (no custom tt)
(
$(
$(#[$meta:meta])*
$(unsafe)? $($vis:vis,? )? $wrapper:ident$(<$($lifetime:lifetime),+>)?$( : $ty:ty)? => $path:path $(,)? $({
$($body:block)+
})? $(,)?
$(,)?)+
) => {
$(
$(#[$meta])*
$($vis)? struct $wrapper<$($lifetime),*>$(($ty))?;
$(
impl$(<$($lifetime),+>)? std::ops::Deref for $wrapper$(<$($lifetime),+>)? {
type Target = $ty;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl$(<$($lifetime),+>)? std::ops::DerefMut for $wrapper$(<$($lifetime),+>)? {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
)?
$(unsafe)? impl$(<$($lifetime),+>)? $path for $wrapper$(<$($lifetime),+>)? {
$($($body)+)?
}
)+
};
// Match multiple types with the same custom implementation logic (without wrapping)
// (
// $(
// $(#[$meta:meta])*
// unsafe $wrapper:ty => $path:path {
// $($body:tt)+
// }
// $(,)?)+ $(,)?
// ) => {
// $(
// $(#[$meta])*
// unsafe impl $path for $wrapper {
// $($body)+
// }
// )+
// };
// Match multiple types with the same custom implementation logic (without wrapping)
(
$(
$(#[$meta:meta])*
unsafe $wrapper:ty => $path:path $({
$($body:tt)+
})*
$(,)?)+ $(,)?
) => {
$(
$(#[$meta])*
unsafe impl $path for $wrapper {
$($($body)+)*
}
)+
};
// Match multiple types with the same custom implementation logic (without wrapping)
(
$(
$(#[$meta:meta])*
$wrapper:ty => $path:path $({
$($body:tt)+
})*
$(,)?)+ $(,)?
) => {
$(
$(#[$meta])*
impl $path for $wrapper {
$($($body)+)*
}
)+
};
// Match multiple types with the same existing implementation logic (without wrapping)
(
$(
$(#[$meta:meta])*
$(unsafe)? $wrapper:ty => $path:path
$(,)?)+ $(,)?
) => {
$(
$(#[$meta])*
$(unsafe)? impl $path for $wrapper {}
)+
};
// Match multiple types with the same existing implementation logic (without wrapping)
(
$(
$(#[$meta:meta])*
($($wrapper:ty $(|)?)+) => $path:path
$(,)?)+ $(,)?
) => {
$(
$(#[$meta])*
impl $path for $wrapper {}
)+
};
(
$(
$(#[$meta:meta])*
$wrapper:ty => $path:path
$(,)?)+ $(,)?
) => {
$(
$(#[$meta])*
impl $path for $wrapper {}
)+
};
// Match multiple types without external wrapping but with custom implementation logic
(
$(
$(#[$meta:meta])*
$wrapper:ty => $({
$($body:tt)+
}$(|)?)+
$(,)?)+
) => {
$(
$(#[$meta])*
$(
impl $wrapper {
$($body)+
}
)+
)+
};
// Match multiple types without external wrapping but with custom implementation logic
(
$(
$(#[$meta:meta])*
unsafe $wrapper:ty {
$($body:tt)+
}
$(,)?)+
) => {
$(
$(#[$meta])*
unsafe impl $wrapper {
$($body)+
}
)+
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment