Skip to main content

rust_macios/objective_c_runtime/
macros.rs

1pub use rust_macios_objective_c_runtime_proc_macros::*;
2
3/// The given name must be a valid Objective-C class that inherits NSObject.
4#[macro_export]
5macro_rules! object {
6    (
7        $(#[$m:meta])*
8        unsafe $v:vis struct $name:ident $(;)?
9    ) => {
10        object! {
11            $(#[$m])*
12            unsafe $v struct $name<> {,}
13        }
14    };
15    (
16        $(#[$m:meta])*
17        unsafe $v:vis struct $name:ident<$($t:ident $(: $b:ident)?),*> {
18            $($p:ident: $pty:ty),*$(,)+
19        }
20    ) => {
21        $(#[$m])*
22        #[repr(C)]
23        $v struct $name<$($t $(: $b)?),*> {
24            /// The raw pointer to the Objective-C object.
25            pub ptr: $crate::objective_c_runtime::Id<$crate::objective_c_runtime::runtime::Object>,
26            // Additional fields (should only be zero-sized PhantomData).
27            $($p : $pty,)*
28        }
29
30        impl<$($t $(: $b)?),*> $crate::objective_c_runtime::traits::PNSObject for $name<$($t),*> {
31            fn m_class<'a>() -> &'a $crate::objective_c_runtime::runtime::Class {
32                $crate::objective_c_runtime::class!($name)
33            }
34
35            fn m_self(&self) -> $crate::objective_c_runtime::id {
36                use $crate::objective_c_runtime::{msg_send, sel, sel_impl};
37                unsafe { msg_send![&*self.ptr, self] }
38            }
39        }
40
41        impl<$($t: core::hash::Hash $(+ $b)?),*> ::core::hash::Hash for $name<$($t),*> {
42            #[inline]
43            fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
44                use $crate::objective_c_runtime::traits::PNSObject;
45                self.p_hash().hash(state);
46            }
47        }
48
49        impl<$($t $(: $b)?),*> core::fmt::Debug for $name<$($t),*> {
50            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
51                use $crate::objective_c_runtime::traits::PNSObject;
52                std::write!(f, "{}", self.p_debug_description())
53            }
54        }
55
56        impl<$($t $(: $b)?),*> core::fmt::Display for $name<$($t),*> {
57            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
58                use $crate::objective_c_runtime::traits::PNSObject;
59                std::write!(f, "{}", self.p_description())
60            }
61        }
62
63        impl<$($t $(: $b)?),*> $crate::objective_c_runtime::traits::ToId for $name<$($t),*> {
64            fn to_id(mut self) -> $crate::objective_c_runtime::id {
65                &mut *self.ptr
66            }
67        }
68
69        impl<$($t $(: $b)?),*> $crate::objective_c_runtime::traits::FromId for $name<$($t),*> {
70            unsafe fn from_id(ptr: $crate::objective_c_runtime::id) -> Self {
71                Self {
72                    ptr: $crate::objective_c_runtime::Id::from_ptr(ptr),
73                     $($p: std::marker::PhantomData),*
74                }
75            }
76        }
77
78        impl<$($t $(: $b)?),*> Clone for $name<$($t),*> {
79            fn clone(&self) -> Self {
80                use $crate::objective_c_runtime::{traits::{FromId, PNSObject}, msg_send, sel, sel_impl};
81                unsafe { Self::from_id(msg_send![self.m_self(), retain]) }
82            }
83        }
84
85        impl<$($t $(: $b)?),*> core::ops::Deref for $name<$($t),*> {
86            type Target = $crate::objective_c_runtime::runtime::Object;
87
88            fn deref(&self) -> &Self::Target {
89                use $crate::objective_c_runtime::traits::PNSObject;
90                unsafe { &*self.m_self() }
91            }
92        }
93
94        impl<$($t $(: $b)?),*> core::ops::DerefMut for $name<$($t),*> {
95            fn deref_mut(&mut self) -> &mut $crate::objective_c_runtime::runtime::Object {
96                use $crate::objective_c_runtime::traits::PNSObject;
97                unsafe { &mut *self.m_self()}
98            }
99        }
100
101        unsafe impl<$($t $(: $b)?),*> $crate::objective_c_runtime::Encode for $name<$($t),*> {
102            fn encode() -> $crate::objective_c_runtime::Encoding {
103                unsafe { $crate::objective_c_runtime::Encoding::from_str("@") }
104            }
105        }
106    };
107}
108
109/// The given name must be a valid Objective-C class that inherits NSObject.
110#[macro_export]
111macro_rules! shared_object {
112    (
113        $(#[$m:meta])*
114        unsafe $v:vis struct $name:ident<$($t:ident $(: $b:ident)?),*> {
115            $($p:ident: $pty:ty),*$(,)+
116        }
117    ) => {
118        $(#[$m])*
119        #[repr(C)]
120        $v struct $name<$($t $(: $b)?),*> {
121            /// The raw pointer to the Objective-C object.
122            pub ptr: $crate::objective_c_runtime::ShareId<$crate::objective_c_runtime::runtime::Object>,
123            // Additional fields (should only be zero-sized PhantomData).
124            $($p: $pty),*
125        }
126
127        impl<$($t $(: $b)?),*> $crate::objective_c_runtime::traits::PNSObject for $name<$($t),*> {
128            fn m_class<'a>() -> &'a $crate::objective_c_runtime::runtime::Class {
129                $crate::objective_c_runtime::class!($name)
130            }
131
132            fn m_self(&self) -> $crate::objective_c_runtime::id {
133                use $crate::objective_c_runtime::{msg_send, sel, sel_impl};
134                unsafe { msg_send![&*self.ptr, self] }
135            }
136        }
137
138        impl<$($t: core::hash::Hash $(+ $b)?),*> ::core::hash::Hash for $name<$($t),*> {
139            #[inline]
140            fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
141                use $crate::objective_c_runtime::traits::PNSObject;
142                self.p_hash().hash(state);
143            }
144        }
145
146        impl<$($t $(: $b)?),*> core::fmt::Debug for $name<$($t),*> {
147            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
148                use $crate::objective_c_runtime::traits::PNSObject;
149                std::write!(f, "{}", self.p_debug_description())
150            }
151        }
152
153        impl<$($t $(: $b)?),*> core::fmt::Display for $name<$($t),*> {
154            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
155                use $crate::objective_c_runtime::traits::PNSObject;
156                std::write!(f, "{}", self.p_description())
157            }
158        }
159
160        impl<$($t $(: $b)?),*> $crate::objective_c_runtime::traits::ToId for $name<$($t),*> {
161            fn to_id(self) -> $crate::objective_c_runtime::id {
162                use $crate::objective_c_runtime::traits::PNSObject;
163                self.m_self()
164            }
165        }
166
167        impl<$($t $(: $b)?),*> $crate::objective_c_runtime::traits::FromId for $name<$($t),*> {
168            unsafe fn from_id(ptr: $crate::objective_c_runtime::id) -> Self {
169                Self {
170                    ptr: $crate::objective_c_runtime::Id::from_ptr(ptr),
171                    $($p: std::marker::PhantomData),*
172                }
173            }
174        }
175
176        impl<$($t $(: $b)?),*> Clone for $name<$($t),*> {
177            fn clone(&self) -> Self {
178                use $crate::objective_c_runtime::{traits::{FromId, PNSObject}, msg_send, sel, sel_impl};
179                unsafe { Self::from_id(msg_send![self.m_self(), retain]) }
180            }
181        }
182
183        impl<$($t $(: $b)?),*> core::ops::Deref for $name<$($t),*> {
184            type Target = $crate::objective_c_runtime::runtime::Object;
185
186            fn deref(&self) -> &Self::Target {
187                use $crate::objective_c_runtime::traits::PNSObject;
188                unsafe { &*self.m_self() }
189            }
190        }
191
192        impl<$($t $(: $b)?),*> core::ops::DerefMut for $name<$($t),*> {
193            fn deref_mut(&mut self) -> &mut $crate::objective_c_runtime::runtime::Object {
194                use $crate::objective_c_runtime::traits::PNSObject;
195                unsafe { &mut *self.m_self()}
196            }
197        }
198
199    };
200}