#![doc = include_str!("../README.md")]
#![no_std]
#[doc(hidden)]
pub mod _re {
pub use core::{
clone::Clone,
cmp::{self, Eq, Ord, PartialEq, PartialOrd},
default::Default,
fmt::{self, Debug},
hash::{Hash, Hasher},
marker::{Copy, PhantomData},
};
}
#[macro_export]
macro_rules! marker {
($(
$(#[$meta:meta])*
$vis:vis struct $name:ident $(<$inner_vis:vis $typaram:ident $(= $default_ty:ty)?>)?
);* $(;)?) => {$(
$crate::marker!{@single {
$(#[$meta])*
$vis struct $name $(<$inner_vis $typaram $(= $default_ty)?>)?;
}}
)*};
(@single {
$(#[$meta:meta])*
$vis:vis struct $name:ident $(;)?
}) => {
$crate::marker!{@single {
$(#[$meta])*
$vis struct $name <pub T>;
}}
};
(@single {
$(#[$meta:meta])*
$vis:vis struct $name:ident<$inner_vis:vis $typaram:ident $(= $default_ty:ty)?> $(;)?
}) => {
$(#[$meta])*
$vis struct $name <$typaram $(= $default_ty)?>($inner_vis $crate::_re::PhantomData<$typaram>);
impl <$typaram> $crate::_re::Copy for $name<$typaram> {}
impl <$typaram> $crate::_re::Clone for $name<$typaram> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
impl<$typaram> $crate::_re::Default for $name<$typaram> {
#[inline]
fn default() -> Self { Self($crate::_re::PhantomData::default()) }
}
impl<$typaram> $crate::_re::Debug for $name<$typaram> {
fn fmt(&self, f: &mut $crate::_re::fmt::Formatter<'_>) -> $crate::_re::fmt::Result {
f.debug_tuple(stringify!($name))
.field(&self.0)
.finish()
}
}
impl<$typaram> $crate::_re::PartialEq for $name<$typaram> {
#[inline(always)]
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<$typaram> $crate::_re::Eq for $name<$typaram> {}
#[expect(clippy::non_canonical_partial_ord_impl, reason = "Matching PhantomData")]
impl<$typaram> $crate::_re::PartialOrd for $name<$typaram> {
#[inline(always)]
fn partial_cmp(&self, other: &Self) -> Option<$crate::_re::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl<$typaram> $crate::_re::Ord for $name<$typaram> {
#[inline(always)]
fn cmp(&self, other: &Self) -> $crate::_re::cmp::Ordering {
self.0.cmp(&other.0)
}
}
impl<$typaram> $crate::_re::Hash for $name<$typaram> {
#[inline(always)]
fn hash<H: $crate::_re::Hasher>(&self, h: &mut H) { self.0.hash(h) }
}
}
}
#[cfg(test)]
mod test {
marker! {
#[expect(dead_code)]
pub struct ParamFormatA;
#[expect(dead_code)]
struct ParamFormatB<pub(crate) MyTypeName>;
#[expect(dead_code)]
struct ParamFormatC<pub(crate) MyTypeName = core::iter::Once<usize>>;
}
}