#[macro_export]
macro_rules! const_assert {
($x:expr $(; $message:expr)?) => {
const _: () = {
if !$x {
panic!(concat!("assertion ", stringify!($x), " failed" $(, ": ", $message)?))
}
};
}
}
#[macro_export]
macro_rules! impl_to_hex_from_lower_hex {
($t:ident, $hex_len_fn:expr) => {
impl $t {
pub fn to_hex(&self) -> alloc::string::String {
use core::fmt::Write;
let mut hex_string = alloc::string::String::with_capacity($hex_len_fn(self));
write!(&mut hex_string, "{:x}", self).expect("writing to string shouldn't fail");
hex_string
}
}
};
}
#[macro_export]
macro_rules! transparent_newtype {
(
$(#[$($struct_attr:tt)*])*
$vis:vis struct $newtype:tt$(<$gen:ident $(= $default:ty)?>)?($($fields:tt)+) $(where $($where_ty:ty: $bound:path),* $(,)?)?;
impl$(<$gen2:tt>)? $newtype2:ident$(<$gen3:tt>)? {
$(
$(#[$($fn_attr:tt)*])*
$fn_vis:vis $(const)? fn $fn:ident($fn_arg_name:ident: $($fn_arg_ty:tt)+) -> $fn_ret_ty:ty;
)*
}
) => {
$crate::_check_tts_eq!($newtype2, $newtype, "the type name in the impl block doesn't match the struct name");
$(
$crate::_check_tts_eq!($gen2, $gen, "the name of the left generic parameter in impl block doesn't match the one on struct");
$crate::_check_tts_eq!($gen3, $gen, "the name of the right generic parameter in impl block doesn't match the one on struct");
)?
$(#[$($struct_attr)*])*
#[repr(transparent)]
$vis struct $newtype$(<$gen $(= $default)?>)?($($fields)+) $(where $($where_ty: $bound),*)?;
impl$(<$gen2>)? $newtype$(<$gen3>)? $(where $($where_ty: $bound),*)? {
$crate::_transparent_ref_conversions! {
$crate::_transparent_newtype_inner_type!($($fields)+);
$(
$(#[$($fn_attr)*])*
$fn_vis fn $fn($fn_arg_name: $($fn_arg_ty)+) -> $fn_ret_ty;
)+
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! _transparent_ref_conversions {
(
$inner:ty;
$(
$(#[$($fn_attr:tt)*])*
$fn_vis:vis $(const)? fn $fn:ident($fn_arg_name:ident: $($fn_arg_ty:tt)+) -> $fn_ret_ty:ty;
)+
) => {
$(
$crate::_transparent_ref_conversion! {
$inner;
$(#[$($fn_attr)*])*
$fn_vis fn $fn($fn_arg_name: $($fn_arg_ty)+) -> $fn_ret_ty;
}
)+
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! _transparent_ref_conversion {
(
$inner:ty;
$(#[$($from_ref_attr:tt)*])*
$from_ref_vis:vis fn $from_ref:ident($from_ref_arg_name:ident: &_) -> $fn_ret_ty:ty;
) => {
#[inline]
$(#[$($from_ref_attr)*])*
$from_ref_vis const fn $from_ref($from_ref_arg_name: &$inner) -> &Self {
unsafe { &*($from_ref_arg_name as *const $inner as *const Self) }
}
};
(
$inner:ty;
$(#[$($from_mut_attr:tt)*])*
$from_mut_vis:vis fn $from_mut:ident($from_mut_arg_name:ident: &mut _) -> $fn_ret_ty:ty;
) => {
#[inline]
$(#[$($from_mut_attr)*])*
$from_mut_vis fn $from_mut($from_mut_arg_name: &mut $inner) -> &mut Self {
unsafe { &mut *($from_mut_arg_name as *mut $inner as *mut Self) }
}
};
(
$inner:ty;
$(#[$($from_box_attr:tt)*])*
$from_box_vis:vis fn $from_box:ident($from_box_arg_name:ident: Box<_>) -> $fn_ret_ty:ty;
) => {
$crate::_emit_alloc! {
$(#[$($from_box_attr)*])*
#[inline]
$from_box_vis fn $from_box($from_box_arg_name: $crate::_export::alloc::boxed::Box<$inner>) -> $crate::_export::alloc::boxed::Box<Self> {
let ptr = $crate::_export::alloc::boxed::Box::into_raw($from_box_arg_name);
unsafe { $crate::_export::alloc::boxed::Box::from_raw(ptr as *mut Self) }
}
}
};
(
$inner:ty;
$(#[$($from_rc_attr:tt)*])*
$from_rc_vis:vis fn $from_rc:ident($from_rc_arg_name:ident: Rc<_>) -> $fn_ret_ty:ty;
) => {
$crate::_emit_alloc! {
$(#[$($from_rc_attr)*])*
#[inline]
$from_rc_vis fn $from_rc($from_rc_arg_name: $crate::_export::alloc::rc::Rc<$inner>) -> $crate::_export::alloc::rc::Rc<Self> {
let ptr = $crate::_export::alloc::rc::Rc::into_raw($from_rc_arg_name);
unsafe { $crate::_export::alloc::rc::Rc::from_raw(ptr as *mut Self) }
}
}
};
(
$inner:ty;
$(#[$($from_arc_attr:tt)*])*
$from_arc_vis:vis fn $from_arc:ident($from_arc_arg_name:ident: Arc<_>) -> $fn_ret_ty:ty;
) => {
$crate::_emit_alloc! {
$(#[$($from_arc_attr)*])*
#[cfg(target_has_atomic = "ptr")]
#[inline]
$from_arc_vis fn $from_arc($from_arc_arg_name: $crate::_export::alloc::sync::Arc<$inner>) -> $crate::_export::alloc::sync::Arc<Self> {
let ptr = $crate::_export::alloc::sync::Arc::into_raw($from_arc_arg_name);
unsafe { $crate::_export::alloc::sync::Arc::from_raw(ptr as *mut Self) }
}
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! _check_tts_eq {
($left:tt, $right:tt, $message:literal) => {
macro_rules! token_eq {
($right) => {};
($any:tt) => {
compile_error!($message)
};
}
token_eq!($left);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! _transparent_newtype_inner_type {
($(#[$($field_attr:tt)*])* $inner:ty) => {
$inner
};
($(#[$($phantom_attr:tt)*])* PhantomData<$phantom:ty>, $(#[$($field_attr:tt)*])* $inner:ty) => {
$inner
};
}
#[cfg(feature = "alloc")]
#[doc(hidden)]
#[macro_export]
macro_rules! _emit_alloc {
($($tokens:tt)*) => { $($tokens)* };
}
#[cfg(not(feature = "alloc"))]
#[doc(hidden)]
#[macro_export]
macro_rules! _emit_alloc {
($($tokens:tt)*) => {};
}
#[macro_export]
macro_rules! impl_array_newtype {
($thing:ident, $ty:ty, $len:literal) => {
impl $thing {
#[inline]
pub fn from_byte_array(bytes: [u8; $len]) -> Self { Self(bytes) }
#[inline]
pub fn as_byte_array(&self) -> &[u8; $len] { &self.0 }
#[inline]
pub fn to_byte_array(self) -> [u8; $len] {
fn check_copy<T: Copy>() {}
check_copy::<$thing>();
self.0
}
#[inline]
pub fn to_vec(self) -> alloc::vec::Vec<u8> { self.0.to_vec() }
#[inline]
pub fn as_bytes(&self) -> &[u8] { &self.0 }
#[inline]
pub fn as_ptr(&self) -> *const $ty {
let &$thing(ref dat) = self;
dat.as_ptr()
}
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut $ty {
let &mut $thing(ref mut dat) = self;
dat.as_mut_ptr()
}
#[inline]
pub fn len(&self) -> usize { $len }
#[inline]
pub fn is_empty(&self) -> bool { false }
}
impl<'a> core::convert::From<[$ty; $len]> for $thing {
fn from(data: [$ty; $len]) -> Self { $thing(data) }
}
impl<'a> core::convert::From<&'a [$ty; $len]> for $thing {
fn from(data: &'a [$ty; $len]) -> Self { $thing(*data) }
}
impl<'a> core::convert::TryFrom<&'a [$ty]> for $thing {
type Error = core::array::TryFromSliceError;
fn try_from(data: &'a [$ty]) -> core::result::Result<Self, Self::Error> {
use core::convert::TryInto;
Ok($thing(data.try_into()?))
}
}
impl AsRef<[$ty; $len]> for $thing {
fn as_ref(&self) -> &[$ty; $len] { &self.0 }
}
impl AsMut<[$ty; $len]> for $thing {
fn as_mut(&mut self) -> &mut [$ty; $len] { &mut self.0 }
}
impl AsRef<[$ty]> for $thing {
fn as_ref(&self) -> &[$ty] { &self.0 }
}
impl AsMut<[$ty]> for $thing {
fn as_mut(&mut self) -> &mut [$ty] { &mut self.0 }
}
impl core::borrow::Borrow<[$ty; $len]> for $thing {
fn borrow(&self) -> &[$ty; $len] { &self.0 }
}
impl core::borrow::BorrowMut<[$ty; $len]> for $thing {
fn borrow_mut(&mut self) -> &mut [$ty; $len] { &mut self.0 }
}
impl core::borrow::Borrow<[$ty]> for $thing {
fn borrow(&self) -> &[$ty] { &self.0 }
}
impl core::borrow::BorrowMut<[$ty]> for $thing {
fn borrow_mut(&mut self) -> &mut [$ty] { &mut self.0 }
}
impl<I> core::ops::Index<I> for $thing
where
[$ty]: core::ops::Index<I>,
{
type Output = <[$ty] as core::ops::Index<I>>::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output { &self.0[index] }
}
};
}