#[doc(alias = "@interface")]
#[macro_export]
macro_rules! extern_class {
(
$(#[$m:meta])*
$v:vis struct $name:ident;
unsafe impl ClassType for $for:ty {
$(#[inherits($($inheritance_rest:ty),+)])?
type Super = $superclass:ty;
}
) => {
$crate::extern_class!(
$(#[$m])*
$v struct $name {}
unsafe impl ClassType for $for {
$(#[inherits($($inheritance_rest),+)])?
type Super = $superclass;
}
);
};
(
$(#[$m:meta])*
$v:vis struct $name:ident {
$($field_vis:vis $field:ident: $field_ty:ty,)*
}
unsafe impl ClassType for $for:ty {
$(#[inherits($($inheritance_rest:ty),+)])?
type Super = $superclass:ty;
}
) => {
$crate::__inner_extern_class!(
$(#[$m])*
$v struct $name<> {
$($field_vis $field: $field_ty,)*
}
unsafe impl<> ClassType for $for {
$(#[inherits($($inheritance_rest),+)])?
type Super = $superclass;
}
);
const _: () = {
if $crate::__macro_helpers::size_of::<$name>() != 0 {
panic!(concat!(
"the struct ",
stringify!($name),
" is not zero-sized!",
))
}
};
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __impl_as_ref_borrow {
{
impl ($($t:tt)*) for $for:ty;
} => {};
{
impl ($($t:tt)*) for $for:ty; $item:ty, $($tail:ty,)*
} => {
impl<$($t)*> $crate::__macro_helpers::AsRef<$item> for $for {
#[inline]
fn as_ref(&self) -> &$item {
&*self
}
}
impl<$($t)*> $crate::__macro_helpers::AsMut<$item> for $for {
#[inline]
fn as_mut(&mut self) -> &mut $item {
&mut *self
}
}
impl<$($t)*> $crate::__macro_helpers::Borrow<$item> for $for {
#[inline]
fn borrow(&self) -> &$item {
&*self
}
}
impl<$($t)*> $crate::__macro_helpers::BorrowMut<$item> for $for {
#[inline]
fn borrow_mut(&mut self) -> &mut $item {
&mut *self
}
}
$crate::__impl_as_ref_borrow! {
impl ($($t)*) for $for; $($tail,)*
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __inner_extern_class {
(
$(#[$m:meta])*
$v:vis struct $name:ident<$($t_struct:ident $(: $b_struct:ident $(= $default:ty)?)?),*> {
$($field_vis:vis $field:ident: $field_ty:ty,)*
}
unsafe impl<$($t_for:ident $(: $b_for:ident)?),*> ClassType for $for:ty {
$(#[inherits($($inheritance_rest:ty),+)])?
type Super = $superclass:ty;
}
) => {
$crate::__inner_extern_class! {
@__inner
$(#[$m])*
$v struct $name ($($t_struct $(: $b_struct $(= $default)?)?),*) {
$($field_vis $field: $field_ty,)*
}
unsafe impl ($($t_for $(: $b_for)?),*) for $for {
INHERITS = [$superclass, $($($inheritance_rest,)+)? $crate::runtime::Object];
}
}
unsafe impl<$($t_for $(: $b_for)?),*> ClassType for $for {
type Super = $superclass;
const NAME: &'static str = stringify!($name);
#[inline]
fn class() -> &'static $crate::runtime::Class {
$crate::class!($name)
}
#[inline]
fn as_super(&self) -> &Self::Super {
&self.__inner
}
#[inline]
fn as_super_mut(&mut self) -> &mut Self::Super {
&mut self.__inner
}
}
};
(
@__inner
$(#[$m:meta])*
$v:vis struct $name:ident ($($t_struct:tt)*) {
$($field_vis:vis $field:ident: $field_ty:ty,)*
}
unsafe impl ($($t:tt)*) for $for:ty {
INHERITS = [$superclass:ty $(, $inheritance_rest:ty)*];
}
) => {
$(#[$m])*
#[repr(C)]
$v struct $name<$($t_struct)*> {
__inner: $superclass,
$($field_vis $field: $field_ty,)*
}
unsafe impl<$($t)*> $crate::RefEncode for $for {
const ENCODING_REF: $crate::Encoding
= <$superclass as $crate::RefEncode>::ENCODING_REF;
}
unsafe impl<$($t)*> $crate::Message for $for {}
impl<$($t)*> $crate::__macro_helpers::Deref for $for {
type Target = $superclass;
#[inline]
fn deref(&self) -> &Self::Target {
&self.__inner
}
}
impl<$($t)*> $crate::__macro_helpers::DerefMut for $for {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.__inner
}
}
impl<$($t)*> $crate::__macro_helpers::AsRef<Self> for $for {
#[inline]
fn as_ref(&self) -> &Self {
self
}
}
impl<$($t)*> $crate::__macro_helpers::AsMut<Self> for $for {
#[inline]
fn as_mut(&mut self) -> &mut Self {
self
}
}
$crate::__impl_as_ref_borrow! {
impl ($($t)*) for $for; $superclass, $($inheritance_rest,)*
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __attribute_helper {
{
@strip_sel
@[sel($($_sel_args:tt)*)]
$(@[$($m_rest:tt)*])*
$(#[$($m:tt)*])*
($($fn:tt)*)
} => {
$crate::__attribute_helper! {
@strip_sel
$(@[$($m_rest)*])*
$(#[$($m)*])*
($($fn)*)
}
};
{
@strip_sel
@[$($m_checked:tt)*]
$(@[$($m_rest:tt)*])*
$(#[$($m:tt)*])*
($($fn:tt)*)
} => {
$crate::__attribute_helper! {
@strip_sel
$(@[$($m_rest)*])*
$(#[$($m)*])*
#[$($m_checked)*]
($($fn)*)
}
};
{
@strip_sel
$(#[$($m:tt)*])*
($($fn:tt)*)
} => {
$(#[$($m)*])*
$($fn)*
};
{
@extract_sel
($out_macro:path)
(
#[sel($($sel:tt)*)]
$($rest:tt)*
)
$($macro_args:tt)*
} => {{
$crate::__attribute_helper! {
@extract_sel_duplicate
$($rest)*
}
$out_macro!(
$($macro_args)*
@($($sel)*)
)
}};
{
@extract_sel
($out_macro:path)
(
#[$($m_checked:tt)*]
$($rest:tt)*
)
$($macro_args:tt)*
} => {{
$crate::__attribute_helper! {
@extract_sel
($out_macro)
($($rest)*)
$($macro_args)*
}
}};
{
@extract_sel
($out_macro:path)
()
$($macro_args:tt)*
} => {{
compile_error!("Must specify the desired selector using `#[sel(...)]`");
}};
{
@extract_sel_duplicate
#[sel($($_sel_args:tt)*)]
$($rest:tt)*
} => {{
compile_error!("Cannot not specify a selector twice!");
}};
{
@extract_sel_duplicate
#[$($m_checked:tt)*]
$($rest:tt)*
} => {{
$crate::__attribute_helper! {
@extract_sel_duplicate
$($rest)*
}
}};
{@extract_sel_duplicate} => {};
}