Source code
Revision control
Copy as Markdown
Other Tools
/// Implement a protocol for an external class.
///
/// This creates a given protocol implementation with regards to the
/// type-system. Useful on types created with [`extern_class!`], not use this
/// on custom classes created with [`define_class!`], instead, implement the
/// protocol within that macro.
///
/// [`define_class!`]: crate::define_class!
///
/// # Examples
///
/// ```
/// # #[cfg(not_available)]
/// use objc2_foundation::NSObjectProtocol;
/// # use objc2::runtime::NSObjectProtocol;
/// use objc2::runtime::NSObject;
/// use objc2::{extern_class, extern_conformance};
///
/// extern_class!(
/// #[unsafe(super(NSObject))]
/// #[derive(PartialEq, Eq, Hash, Debug)]
/// pub struct MyClass;
/// );
///
/// // SAFETY: The class `MyClass` conforms to the `NSObject` protocol (since
/// // its superclass `NSObject` does).
/// extern_conformance!(unsafe impl NSObjectProtocol for MyClass {});
/// ```
///
/// See the [`extern_class!`] macro for more examples.
///
/// [`extern_class!`]: crate::extern_class!
#[doc(alias = "@interface")]
#[macro_export]
macro_rules! extern_conformance {
(unsafe impl $(<$($t:ident : $($bound:ident)? $(?$sized:ident)? $(+ $b:path)*),* $(,)?>)? $ty:ident for $protocol:ty {}) => {
unsafe impl $(<$($t : $($bound)? $(?$sized)? $(+ $b)*),*>)? $ty for $protocol {
// TODO(breaking): Add private marker here.
}
};
}
#[cfg(test)]
mod tests {
use crate::runtime::NSObject;
use crate::{extern_class, extern_protocol};
extern_class!(
#[unsafe(super(NSObject))]
#[name = "NSObject"]
struct OldSyntax;
);
extern_protocol!(
#[name = "NSObjectProtocol"]
#[allow(clippy::missing_safety_doc)]
unsafe trait Protocol {}
);
// Old syntax, must continue to work until next breaking version.
unsafe impl Protocol for OldSyntax {}
}