#[macro_export]
macro_rules! impl_slice_spec_methods {
(
field=$field:tt;
methods=[$($method:ident),* $(,)?];
) => {
$(
$crate::impl_slice_spec_methods! {
@impl; ($field);
$method
}
)*
};
(@impl; ($field:tt); as_inner) => {
#[inline]
fn as_inner(s: &Self::Custom) -> &Self::Inner {
&s.$field
}
};
(@impl; ($field:tt); as_inner_mut) => {
#[inline]
fn as_inner_mut(s: &mut Self::Custom) -> &mut Self::Inner {
&mut s.$field
}
};
(@impl; ($field:tt); from_inner_unchecked) => {
#[inline]
unsafe fn from_inner_unchecked(s: &Self::Inner) -> &Self::Custom {
&*(s as *const Self::Inner as *const Self::Custom)
}
};
(@impl; ($field:tt); from_inner_unchecked_mut) => {
#[inline]
unsafe fn from_inner_unchecked_mut(s: &mut Self::Inner) -> &mut Self::Custom {
&mut *(s as *mut Self::Inner as *mut Self::Custom)
}
};
}
#[macro_export]
macro_rules! impl_std_traits_for_slice {
(
Spec {
spec: $spec:ty,
custom: $custom:ty,
inner: $inner:ty,
error: $error:ty,
};
$({$($rest:tt)*});* $(;)?
) => {
$(
$crate::impl_std_traits_for_slice! {
@impl; ({std, std}, $spec, $custom, $inner, $error);
rest=[$($rest)*];
}
)*
};
(
Std {
core: $core:ident,
alloc: $alloc:ident,
};
Spec {
spec: $spec:ty,
custom: $custom:ty,
inner: $inner:ty,
error: $error:ty,
};
$({$($rest:tt)*});* $(;)?
) => {
$(
$crate::impl_std_traits_for_slice! {
@impl; ({$core, $alloc}, $spec, $custom, $inner, $error);
rest=[$($rest)*];
}
)*
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ AsMut<{Custom}> ];
) => {
impl $core::convert::AsMut<$custom> for $custom {
#[inline]
fn as_mut(&mut self) -> &mut $custom {
self
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ AsMut<$param:ty> ];
) => {
impl $core::convert::AsMut<$param> for $custom
where
$inner: AsMut<$param>,
{
#[inline]
fn as_mut(&mut self) -> &mut $param {
<$spec as $crate::SliceSpec>::as_inner_mut(self).as_mut()
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ AsRef<{Custom}> ];
) => {
impl $core::convert::AsRef<$custom> for $custom {
#[inline]
fn as_ref(&self) -> &$custom {
self
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ AsRef<{Custom}> for Cow<{Custom}> ];
) => {
impl<'a> $core::convert::AsRef<$custom> for $alloc::borrow::Cow<'a, $custom> {
#[inline]
fn as_ref(&self) -> &$custom {
&**self
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ AsRef<$param:ty> ];
) => {
impl $core::convert::AsRef<$param> for $custom
where
$inner: AsRef<$param>,
{
#[inline]
fn as_ref(&self) -> &$param {
<$spec as $crate::SliceSpec>::as_inner(self).as_ref()
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ AsRef<$param:ty> for Cow<{Custom}> ];
) => {
impl<'a> $core::convert::AsRef<$param> for $alloc::borrow::Cow<'a, $custom>
where
$inner: AsRef<$param>,
{
#[inline]
fn as_ref(&self) -> &$param {
<$spec as $crate::SliceSpec>::as_inner(&**self).as_ref()
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ From<&{Inner}> for &{Custom} ];
) => {
impl<'a> $core::convert::From<&'a $inner> for &'a $custom {
fn from(s: &'a $inner) -> Self {
assert!(
<$spec as $crate::SliceSpec>::validate(s).is_ok(),
"Attempt to convert invalid data: `From<&{}> for &{}`",
stringify!($inner), stringify!($custom)
);
unsafe {
<$spec as $crate::SliceSpec>::from_inner_unchecked(s)
}
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ From<&mut {Inner}> for &mut {Custom} ];
) => {
impl<'a> $core::convert::From<&'a mut $inner> for &'a mut $custom {
fn from(s: &'a mut $inner) -> Self {
assert!(
<$spec as $crate::SliceSpec>::validate(s).is_ok(),
"Attempt to convert invalid data: `From<&mut {}> for &mut {}`",
stringify!($inner), stringify!($custom)
);
unsafe {
<$spec as $crate::SliceSpec>::from_inner_unchecked_mut(s)
}
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ From<&{Custom}> for &{Inner} ];
) => {
impl<'a> $core::convert::From<&'a $custom> for &'a $inner {
fn from(s: &'a $custom) -> Self {
<$spec as $crate::SliceSpec>::as_inner(s)
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ From<&mut {Custom}> for &mut {Inner} ];
) => {
impl<'a> $core::convert::From<&'a mut $custom> for &'a mut $inner {
fn from(s: &'a mut $custom) -> Self {
<$spec as $crate::SliceSpec>::as_inner_mut(s)
}
}
};
(
@impl [smartptr]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ From<&{Custom}> for $($smartptr:ident)::* <{Custom}> ];
) => {
impl<'a> $core::convert::From<&'a $custom> for $($smartptr)::* <$custom>
where
$($smartptr)::* <$inner>: $core::convert::From<&'a $inner>,
{
fn from(s: &'a $custom) -> Self {
let inner = <$spec as $crate::SliceSpec>::as_inner(s);
let buf = $($smartptr)::* ::<$inner>::from(inner);
unsafe {
$($smartptr)::* ::<$custom>::from_raw(
$($smartptr)::* ::<$inner>::into_raw(buf) as *mut $custom
)
}
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ From<&{Custom}> for Arc<{Custom}> ];
) => {
$crate::impl_std_traits_for_slice! {
@impl [smartptr]; ({$core, $alloc}, $spec, $custom, $inner, $error);
rest=[ From<&{Custom}> for $alloc::sync::Arc <{Custom}> ];
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ From<&{Custom}> for Box<{Custom}> ];
) => {
$crate::impl_std_traits_for_slice! {
@impl [smartptr]; ({$core, $alloc}, $spec, $custom, $inner, $error);
rest=[ From<&{Custom}> for $alloc::boxed::Box <{Custom}> ];
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ From<&{Custom}> for Rc<{Custom}> ];
) => {
$crate::impl_std_traits_for_slice! {
@impl [smartptr]; ({$core, $alloc}, $spec, $custom, $inner, $error);
rest=[ From<&{Custom}> for $alloc::rc::Rc <{Custom}> ];
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ TryFrom<&{Inner}> for &{Custom} ];
) => {
impl<'a> $core::convert::TryFrom<&'a $inner> for &'a $custom {
type Error = $error;
fn try_from(s: &'a $inner) -> $core::result::Result<Self, Self::Error> {
<$spec as $crate::SliceSpec>::validate(s)?;
Ok(unsafe {
<$spec as $crate::SliceSpec>::from_inner_unchecked(s)
})
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ TryFrom<&mut {Inner}> for &mut {Custom} ];
) => {
impl<'a> $core::convert::TryFrom<&'a mut $inner> for &'a mut $custom {
type Error = $error;
fn try_from(s: &'a mut $inner) -> $core::result::Result<Self, Self::Error> {
<$spec as $crate::SliceSpec>::validate(s)?;
Ok(unsafe {
<$spec as $crate::SliceSpec>::from_inner_unchecked_mut(s)
})
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ Default for &{Custom} ];
) => {
impl<'a> $core::default::Default for &'a $custom
where
&'a $inner: $core::default::Default,
{
fn default() -> Self {
let inner = <&'a $inner as $core::default::Default>::default();
assert!(
<$spec as $crate::SliceSpec>::validate(inner).is_ok(),
"Attempt to create invalid data: `Default for &{}`",
stringify!($custom)
);
unsafe {
<$spec as $crate::SliceSpec>::from_inner_unchecked(inner)
}
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ Default for &mut {Custom} ];
) => {
impl<'a> $core::default::Default for &'a mut $custom
where
&'a mut $inner: $core::default::Default,
{
fn default() -> Self {
let inner = <&'a mut $inner as $core::default::Default>::default();
assert!(
<$spec as $crate::SliceSpec>::validate(inner).is_ok(),
"Attempt to create invalid data: `Default for &{}`",
stringify!($custom)
);
unsafe {
<$spec as $crate::SliceSpec>::from_inner_unchecked_mut(inner)
}
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ Debug ];
) => {
impl $core::fmt::Debug for $custom
where
$inner: $core::fmt::Debug,
{
fn fmt(&self, f: &mut $core::fmt::Formatter<'_>) -> $core::fmt::Result {
let inner = <$spec as $crate::SliceSpec>::as_inner(self);
<$inner as $core::fmt::Debug>::fmt(inner, f)
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ Display ];
) => {
impl $core::fmt::Display for $custom
where
$inner: $core::fmt::Display,
{
fn fmt(&self, f: &mut $core::fmt::Formatter<'_>) -> $core::fmt::Result {
let inner = <$spec as $crate::SliceSpec>::as_inner(self);
<$inner as $core::fmt::Display>::fmt(inner, f)
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ Deref<Target = {Inner}> ];
) => {
impl $core::ops::Deref for $custom {
type Target = $inner;
#[inline]
fn deref(&self) -> &Self::Target {
<$spec as $crate::SliceSpec>::as_inner(self)
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ DerefMut<Target = {Inner}> ];
) => {
impl $core::ops::DerefMut for $custom {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
<$spec as $crate::SliceSpec>::as_inner_mut(self)
}
}
};
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ $($rest:tt)* ];
) => {
compile_error!(concat!("Unsupported target: ", stringify!($($rest)*)));
};
}
#[macro_export]
macro_rules! impl_cmp_for_slice {
(
Spec {
spec: $spec:ty,
custom: $custom:ty,
inner: $inner:ty,
base: $base:ident,
};
Cmp { $($cmp_targets:ident),* };
$($rest:tt)*
) => {
$crate::impl_cmp_for_slice! {
@full;
Std {
core: std,
alloc: std,
};
Spec {
spec: $spec,
custom: $custom,
inner: $inner,
base: $base,
};
Cmp { $($cmp_targets),* };
$($rest)*
}
};
(
Std {
core: $core:ident,
alloc: $alloc:ident,
};
Spec {
spec: $spec:ty,
custom: $custom:ty,
inner: $inner:ty,
base: $base:ident,
};
Cmp { $($cmp_targets:ident),* };
$($rest:tt)*
) => {
$crate::impl_cmp_for_slice! {
@full;
Std {
core: $core,
alloc: $alloc,
};
Spec {
spec: $spec,
custom: $custom,
inner: $inner,
base: $base,
};
Cmp { $($cmp_targets),* };
$($rest)*
}
};
(
@full;
Std {
core: $core:ident,
alloc: $alloc:ident,
};
Spec {
spec: $spec:ty,
custom: $custom:ty,
inner: $inner:ty,
base: $base:ident,
};
Cmp { PartialEq, PartialOrd };
$({ ($($lhs:tt)*), ($($rhs:tt)*) $(, $($opt:ident),*)? });* $(;)?
) => {
$(
$crate::impl_cmp_for_slice! {
@impl[PartialEq]; ({$core, $alloc}, $spec, $custom, $inner, $base);
{ ($($lhs)*), ($($rhs)*) $(, $($opt),*)? };
}
$crate::impl_cmp_for_slice! {
@impl[PartialOrd]; ({$core, $alloc}, $spec, $custom, $inner, $base);
{ ($($lhs)*), ($($rhs)*) $(, $($opt),*)? };
}
)*
};
(
@full;
Std {
core: $core:ident,
alloc: $alloc:ident,
};
Spec {
spec: $spec:ty,
custom: $custom:ty,
inner: $inner:ty,
base: $base:ident,
};
Cmp { PartialEq };
$({ ($($lhs:tt)*), ($($rhs:tt)*) $(, $($opt:ident),*)? });* $(;)?
) => {
$(
$crate::impl_cmp_for_slice! {
@impl[PartialEq]; ({$core, $alloc}, $spec, $custom, $inner, $base);
{ ($($lhs)*), ($($rhs)*) $(, $($opt),*)? };
}
)*
};
(
@full;
Std {
core: $core:ident,
alloc: $alloc:ident,
};
Spec {
spec: $spec:ty,
custom: $custom:ty,
inner: $inner:ty,
base: $base:ident,
};
Cmp { PartialOrd };
$({ ($($lhs:tt)*), ($($rhs:tt)*) $(, $($opt:ident),*)? });* $(;)?
) => {
$(
$crate::impl_cmp_for_slice! {
@impl[PartialOrd]; ({$core, $alloc}, $spec, $custom, $inner, $base);
{ ($($lhs)*), ($($rhs)*) $(, $($opt),*)? };
}
)*
};
(
@impl[PartialEq]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $base:ident);
{ ($($lhs:tt)*), ($($rhs:tt)*) };
) => {
impl $core::cmp::PartialEq<
$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($rhs)* })
> for $crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($lhs)* })
{
#[inline]
fn eq(&self, other: &$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($rhs)* })) -> bool {
$crate::impl_cmp_for_slice!(@cmp_fn[PartialEq]; ($custom, $inner, $base))(
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($lhs)* }; self),
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($rhs)* }; other),
)
}
}
};
(
@impl[PartialEq]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $base:ident);
{ ($($lhs:tt)*), ($($rhs:tt)*), rev };
) => {
impl $core::cmp::PartialEq<
$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($rhs)* })
> for $crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($lhs)* })
{
#[inline]
fn eq(&self, other: &$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($rhs)* })) -> bool {
$crate::impl_cmp_for_slice!(@cmp_fn[PartialEq]; ($custom, $inner, $base))(
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($lhs)* }; self),
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($rhs)* }; other),
)
}
}
impl $core::cmp::PartialEq<
$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($lhs)* })
> for $crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($rhs)* })
{
#[inline]
fn eq(&self, other: &$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($lhs)* })) -> bool {
$crate::impl_cmp_for_slice!(@cmp_fn[PartialEq]; ($custom, $inner, $base))(
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($rhs)* }; self),
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($lhs)* }; other),
)
}
}
};
(
@impl[PartialOrd]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $base:ident);
{ ($($lhs:tt)*), ($($rhs:tt)*) };
) => {
impl $core::cmp::PartialOrd<
$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($rhs)* })
> for $crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($lhs)* })
{
#[inline]
fn partial_cmp(&self, other: &$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($rhs)* }))
-> $core::option::Option<$core::cmp::Ordering>
{
$crate::impl_cmp_for_slice!(@cmp_fn[PartialOrd]; ($custom, $inner, $base))(
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($lhs)* }; self),
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($rhs)* }; other),
)
}
}
};
(
@impl[PartialOrd]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $base:ident);
{ ($($lhs:tt)*), ($($rhs:tt)*), rev };
) => {
impl $core::cmp::PartialOrd<
$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($rhs)* })
> for $crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($lhs)* })
{
#[inline]
fn partial_cmp(&self, other: &$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($rhs)* }))
-> $core::option::Option<$core::cmp::Ordering>
{
$crate::impl_cmp_for_slice!(@cmp_fn[PartialOrd]; ($custom, $inner, $base))(
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($lhs)* }; self),
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($rhs)* }; other),
)
}
}
impl $core::cmp::PartialOrd<
$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($lhs)* })
> for $crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($rhs)* })
{
#[inline]
fn partial_cmp(&self, other: &$crate::impl_cmp_for_slice!(@type; ({$core, $alloc}, $custom, $inner); { $($lhs)* }))
-> $core::option::Option<$core::cmp::Ordering>
{
$crate::impl_cmp_for_slice!(@cmp_fn[PartialOrd]; ($custom, $inner, $base))(
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($rhs)* }; self),
$crate::impl_cmp_for_slice!(@expr[$base]; ({$core, $alloc}, $spec, $custom, $inner); { $($lhs)* }; other),
)
}
}
};
(@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty); { {Custom} }) => { $custom };
(@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty); { &{Custom} }) => { &$custom };
(@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty); { Cow<{Custom}> }) => { $alloc::borrow::Cow<'_, $custom> };
(@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty); { {Inner} }) => { $inner };
(@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty); { &{Inner} }) => { &$inner };
(@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty); { Cow<{Inner}> }) => { $alloc::borrow::Cow<'_, $inner> };
(@type; ({$core:ident, $alloc:ident}, $custom:ty, $inner:ty); { $ty:ty }) => { $ty };
(@cmp_fn[PartialEq]; ($custom:ty, $inner:ty, Inner)) => { <$inner as core::cmp::PartialEq<$inner>>::eq };
(@cmp_fn[PartialEq]; ($custom:ty, $inner:ty, Custom)) => { <$custom as core::cmp::PartialEq<$custom>>::eq };
(@cmp_fn[PartialOrd]; ($custom:ty, $inner:ty, Inner)) => { <$inner as core::cmp::PartialOrd<$inner>>::partial_cmp };
(@cmp_fn[PartialOrd]; ($custom:ty, $inner:ty, Custom)) => { <$custom as core::cmp::PartialOrd<$custom>>::partial_cmp };
(@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { {Custom} }; $expr:expr) => {
<$spec as $crate::SliceSpec>::as_inner($expr)
};
(@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { &{Custom} }; $expr:expr) => {
<$spec as $crate::SliceSpec>::as_inner(*$expr)
};
(@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { Cow<{Custom}> }; $expr:expr) => {
<$spec as $crate::SliceSpec>::as_inner(&**$expr)
};
(@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { {Inner} }; $expr:expr) => {
$expr
};
(@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { &{Inner} }; $expr:expr) => {
*$expr
};
(@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { Cow<{Inner}> }; $expr:expr) => {
&**$expr
};
(@expr[Inner]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { $ty:ty }; $expr:expr) => {
$core::convert::AsRef::<$inner>::as_ref($expr)
};
(@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { {Custom} }; $expr:expr) => {
$expr
};
(@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { &{Custom} }; $expr:expr) => {
*$expr
};
(@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { Cow<{Custom}> }; $expr:expr) => {
&**$expr
};
(@expr[Custom]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty); { $ty:ty }; $expr:expr) => {
$core::convert::AsRef::<$custom>::as_ref($expr)
};
($($rest:tt)*) => {
compile_error!(stringify!($($rest)*));
};
}