Skip to main content

core/os/darwin/
objc.rs

1//! Defines types and macros for Objective-C interoperability.
2
3#![unstable(feature = "darwin_objc", issue = "145496")]
4#![allow(nonstandard_style)]
5
6use crate::fmt;
7
8/// Equivalent to Objective-C’s `struct objc_class` type.
9#[repr(u8)]
10pub enum objc_class {
11    #[unstable(
12        feature = "objc_class_variant",
13        reason = "temporary implementation detail",
14        issue = "none"
15    )]
16    #[doc(hidden)]
17    __variant1,
18    #[unstable(
19        feature = "objc_class_variant",
20        reason = "temporary implementation detail",
21        issue = "none"
22    )]
23    #[doc(hidden)]
24    __variant2,
25}
26
27impl fmt::Debug for objc_class {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        f.debug_struct("objc_class").finish()
30    }
31}
32
33/// Equivalent to Objective-C’s `struct objc_selector` type.
34#[repr(u8)]
35pub enum objc_selector {
36    #[unstable(
37        feature = "objc_selector_variant",
38        reason = "temporary implementation detail",
39        issue = "none"
40    )]
41    #[doc(hidden)]
42    __variant1,
43    #[unstable(
44        feature = "objc_selector_variant",
45        reason = "temporary implementation detail",
46        issue = "none"
47    )]
48    #[doc(hidden)]
49    __variant2,
50}
51
52impl fmt::Debug for objc_selector {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        f.debug_struct("objc_selector").finish()
55    }
56}
57
58/// Equivalent to Objective-C’s `Class` type.
59pub type Class = *mut objc_class;
60
61/// Equivalent to Objective-C’s `SEL` type.
62pub type SEL = *mut objc_selector;
63
64/// Gets a reference to an Objective-C class.
65///
66/// This macro will yield an expression of type [`Class`] for the given class name string literal.
67///
68/// # Example
69///
70#[cfg_attr(target_os = "macos", doc = "```no_run")]
71#[cfg_attr(not(target_os = "macos"), doc = "```ignore (needs macos)")]
72/// #![feature(darwin_objc)]
73/// use core::os::darwin::objc;
74///
75/// let string_class = objc::class!("NSString");
76/// ```
77#[allow_internal_unstable(rustc_attrs)]
78pub macro class($classname:expr) {{
79    // Since static Objective-C class references actually end up with multiple definitions
80    // across dylib boundaries, we only expose the value of the static and don't provide a way to
81    // get the address of or a reference to the static.
82    unsafe extern "C" {
83        #[rustc_objc_class = $classname]
84        safe static VAL: $crate::os::darwin::objc::Class;
85    }
86    VAL
87}}
88
89/// Gets a reference to an Objective-C selector.
90///
91/// This macro will yield an expression of type [`SEL`] for the given method name string literal.
92///
93/// It is similar to Objective-C’s `@selector` directive.
94///
95/// # Examples
96///
97#[cfg_attr(target_os = "macos", doc = "```no_run")]
98#[cfg_attr(not(target_os = "macos"), doc = "```ignore (needs macos)")]
99/// #![feature(darwin_objc)]
100/// use core::os::darwin::objc;
101///
102/// let alloc_sel = objc::selector!("alloc");
103/// let init_sel = objc::selector!("initWithCString:encoding:");
104/// ```
105#[allow_internal_unstable(rustc_attrs)]
106pub macro selector($methname:expr) {{
107    // Since static Objective-C selector references actually end up with multiple definitions
108    // across dylib boundaries, we only expose the value of the static and don't provide a way to
109    // get the address of or a reference to the static.
110    unsafe extern "C" {
111        #[rustc_objc_selector = $methname]
112        safe static VAL: $crate::os::darwin::objc::SEL;
113    }
114    VAL
115}}