#[doc(alias = "@interface")]
#[macro_export]
macro_rules! extern_class {
(
// The following special attributes are supported:
// - #[unsafe(super($($superclasses:path),*))]
$(#[$($attrs:tt)*])*
$v:vis struct $class:ident;
) => {
$crate::__extract_struct_attributes! {
($(#[$($attrs)*])*)
($crate::__extern_class_inner)
($v)
($class)
() }
};
(
$(#[$($attrs:tt)*])*
$v:vis struct $class:ident<
$($generic:ident $(: $(?$bound_sized:ident)? $($bound:ident)?)? $(= $default:ty)?),*
$(,)?
>;
) => {
$crate::__extract_struct_attributes! {
($(#[$($attrs)*])*)
($crate::__extern_class_inner)
($v)
($class)
($(
($generic)
($($(?$bound_sized)? $($bound)?)?)
($($default)?)
)*)
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __extern_class_inner {
(
($v:vis)
($class:ident)
($($(
($generic:ident)
($($($bounds:tt)+)?)
($($default:ty)?)
)+)?)
($($safety:tt $superclass:path $(, $superclasses:path)* $(,)?)?)
($($($thread_kind:tt)+)?)
($($name:tt)*)
($($ivars:tt)*)
($($derives:tt)*)
($($attr_struct:tt)*)
($($attr_impl:tt)*)
) => {
#[repr(C)]
$($attr_struct)*
$v struct $class $(<$($generic $(: $($bounds)+)? $(= $default)?),*>)? {
__superclass: $crate::__fallback_if_not_set! {
($($superclass)?)
($crate::runtime::NSObject)
},
$(__generics: $crate::__macro_helpers::PhantomData<($(*mut $generic),+)>,)?
}
$crate::__extern_class_impl_traits! {
($($attr_impl)*)
(unsafe impl $(<$($generic: $($($bounds)+ +)? $crate::Message),+>)?)
($class $(<$($generic),*>)?)
($($superclass, $($superclasses,)*)? $crate::runtime::AnyObject)
}
$crate::__extern_class_derives! {
($($attr_impl)*)
(impl $(<$($generic: $($($bounds)+)?),+>)?)
($class $(<$($generic),*>)?)
($($derives)*)
}
$($attr_impl)*
unsafe impl $crate::DowncastTarget for $class $(<$($crate::__extern_class_map_anyobject!($generic)),+>)? {}
$($attr_impl)*
unsafe impl $(<$($generic $(: $($bounds)+ + $crate::Message)?),*>)? $crate::ClassType for $class $(<$($generic),*>)? {
type Super = $crate::__fallback_if_not_set! {
($($superclass)?)
($crate::runtime::NSObject)
};
type ThreadKind = $crate::__fallback_if_not_set! {
($(dyn ($($thread_kind)+))?)
(<<Self as $crate::ClassType>::Super as $crate::ClassType>::ThreadKind)
};
const NAME: &'static $crate::__macro_helpers::str = $crate::__fallback_if_not_set! {
($($name)*)
($crate::__macro_helpers::stringify!($class))
};
#[inline]
fn class() -> &'static $crate::runtime::AnyClass {
let _ = <Self as $crate::__macro_helpers::ValidThreadKind<<Self as $crate::ClassType>::ThreadKind>>::check;
let _ = <Self as $crate::__macro_helpers::MainThreadOnlyDoesNotImplSendSync<_>>::check;
let _ = <Self as $crate::__macro_helpers::DoesNotImplDrop<_>>::check;
$crate::__class_inner!($crate::__fallback_if_not_set! {
($($name)*)
($crate::__macro_helpers::stringify!($class))
}, $crate::__hash_idents!($class))
}
#[inline]
fn as_super(&self) -> &Self::Super {
&self.__superclass
}
const __INNER: () = ();
type __SubclassingType = Self;
}
$($attr_impl)*
$crate::__extern_class_check_super_unsafe!($($safety $superclass)?);
$($attr_impl)*
$crate::__extern_class_check_no_ivars!($($ivars)*);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __extern_class_check_super_unsafe {
(unsafe $($superclass:tt)+) => {};
(safe $($superclass:tt)+) => {
$crate::__macro_helpers::compile_error!(
"#[super(...)] must be wrapped in `unsafe`, as in #[unsafe(super(...))]"
);
};
() => {
$crate::__macro_helpers::compile_error!(
"must specify the superclass with #[unsafe(super(...))]"
);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __extern_class_map_anyobject {
($t:ident) => {
$crate::runtime::AnyObject
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __extern_class_check_no_ivars {
() => {};
($($ivars:tt)*) => {
$crate::__macro_helpers::compile_error!("#[ivars] is not supported in extern_class!");
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __extern_class_impl_traits {
(
($($attr_impl:tt)*)
(unsafe impl $($after_impl:tt)*)
($($for:tt)*)
($superclass:path $(, $remaining_superclasses:path)*)
) => {
$($attr_impl)*
unsafe impl $($after_impl)* $crate::RefEncode for $($for)* {
const ENCODING_REF: $crate::Encoding
= <$superclass as $crate::RefEncode>::ENCODING_REF;
}
$($attr_impl)*
unsafe impl $($after_impl)* $crate::Message for $($for)* {}
$($attr_impl)*
impl $($after_impl)* $crate::__macro_helpers::Deref for $($for)* {
type Target = $superclass;
#[inline]
fn deref(&self) -> &Self::Target {
&self.__superclass
}
}
$($attr_impl)*
impl $($after_impl)* $crate::__macro_helpers::AsRef<Self> for $($for)* {
#[inline]
fn as_ref(&self) -> &Self {
self
}
}
$crate::__extern_class_impl_as_ref_borrow! {
($superclass $(, $remaining_superclasses)*)
($($attr_impl)*)
(impl $($after_impl)*)
($($for)*)
fn as_ref(&self) {
&*self
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __extern_class_impl_as_ref_borrow {
{
()
($($attr_impl:tt)*)
(impl $($after_impl:tt)*)
($($for:tt)*)
fn as_ref($($self:tt)*) $as_ref:block
} => {};
{
($superclass:path $(, $remaining_superclasses:path)*)
($($attr_impl:tt)*)
(impl $($after_impl:tt)*)
($($for:tt)*)
fn as_ref($($self:tt)*) $as_ref:block
} => {
$($attr_impl)*
impl $($after_impl)* $crate::__macro_helpers::AsRef<$superclass> for $($for)* {
#[inline]
fn as_ref($($self)*) -> &$superclass $as_ref
}
$($attr_impl)*
impl $($after_impl)* $crate::__macro_helpers::Borrow<$superclass> for $($for)* {
#[inline]
fn borrow($($self)*) -> &$superclass $as_ref
}
$crate::__extern_class_impl_as_ref_borrow! {
($($remaining_superclasses),*)
($($attr_impl)*)
(impl $($after_impl)*)
($($for)*)
fn as_ref($($self)*) $as_ref
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __extern_class_derives {
(
($($attr_impl:tt)*)
(impl $($after_impl:tt)*)
($($for:tt)*)
($(,)*)
) => {};
(
($($attr_impl:tt)*)
(impl $($after_impl:tt)*)
($($for:tt)*)
(
$(,)*
Debug
$($rest:tt)*
)
) => {
$($attr_impl)*
#[automatically_derived]
impl $($after_impl)* $crate::__macro_helpers::fmt::Debug for $($for)* {
fn fmt(&self, f: &mut $crate::__macro_helpers::fmt::Formatter<'_>) -> $crate::__macro_helpers::fmt::Result {
$crate::__macro_helpers::fmt::Debug::fmt(&self.__superclass, f)
}
}
$crate::__extern_class_derives! {
($($attr_impl)*)
(impl $($after_impl)*)
($($for)*)
($($rest)*)
}
};
(
($($attr_impl:tt)*)
(impl $($after_impl:tt)*)
($($for:tt)*)
(
$(,)*
PartialEq
$($rest:tt)*
)
) => {
$($attr_impl)*
#[automatically_derived]
impl $($after_impl)* $crate::__macro_helpers::PartialEq for $($for)* {
#[inline]
fn eq(&self, other: &Self) -> $crate::__macro_helpers::bool {
$crate::__macro_helpers::PartialEq::eq(&self.__superclass, &other.__superclass)
}
}
$crate::__extern_class_derives! {
($($attr_impl)*)
(impl $($after_impl)*)
($($for)*)
($($rest)*)
}
};
(
($($attr_impl:tt)*)
(impl $($after_impl:tt)*)
($($for:tt)*)
(
$(,)*
Eq
$($rest:tt)*
)
) => {
$($attr_impl)*
#[automatically_derived]
impl $($after_impl)* $crate::__macro_helpers::Eq for $($for)* {}
$crate::__extern_class_derives! {
($($attr_impl)*)
(impl $($after_impl)*)
($($for)*)
($($rest)*)
}
};
(
($($attr_impl:tt)*)
(impl $($after_impl:tt)*)
($($for:tt)*)
(
$(,)*
Hash
$($rest:tt)*
)
) => {
$($attr_impl)*
#[automatically_derived]
impl $($after_impl)* $crate::__macro_helpers::Hash for $($for)* {
#[inline]
fn hash<H: $crate::__macro_helpers::Hasher>(&self, state: &mut H) {
$crate::__macro_helpers::Hash::hash(&self.__superclass, state)
}
}
$crate::__extern_class_derives! {
($($attr_impl)*)
(impl $($after_impl)*)
($($for)*)
($($rest)*)
}
};
(
($($attr_impl:tt)*)
(impl $($after_impl:tt)*)
($($for:tt)*)
(
$(,)*
$derive:path
$(, $($rest:tt)*)?
)
) => {
const _: () = {
#[derive($derive)]
struct Derive;
};
$crate::__macro_helpers::compile_error!($crate::__macro_helpers::stringify!(
#[derive($derive)] is not supported in extern_class!
));
$crate::__extern_class_derives! {
($($attr_impl)*)
(impl $($after_impl)*)
($($for)*)
($($($rest)*)?)
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __select_name {
($_name:ident; $name_const:expr) => {
$name_const
};
($name:ident;) => {
$crate::__macro_helpers::stringify!($name)
};
}