1
+ /// Create a new type to represent an Objective-C class.
2
+ ///
3
+ /// The given name should correspond to a valid Objective-C class, whose
4
+ /// instances have the encoding `Encoding::Object` (as an example:
5
+ /// `NSAutoreleasePool` does not have this).
6
+ ///
7
+ ///
8
+ /// # Specification
9
+ ///
10
+ /// This creates an opaque struct, and implements traits for it to allow
11
+ /// easier usage as an Objective-C object.
12
+ ///
13
+ /// The traits [`objc2::RefEncode`] and [`objc2::Message`] are implemented to
14
+ /// allow sending messages to the object and using it in [`objc2::rc::Id`].
15
+ ///
16
+ /// [`Deref`] and [`DerefMut`] are implemented and delegate to the first
17
+ /// superclass (direct parent). Auto traits are inherited from this superclass
18
+ /// as well (this macro effectively just creates a newtype wrapper around the
19
+ /// superclass).
20
+ ///
21
+ /// Finally, [`AsRef`], [`AsMut`], [`Borrow`] and [`BorrowMut`] are
22
+ /// implemented to allow conversion to an arbitary superclasses in the
23
+ /// inheritance chain (since an instance of a class can always be interpreted
24
+ /// as it's superclasses).
25
+ ///
26
+ /// [`Deref`]: core::ops::Deref
27
+ /// [`DerefMut`]: core::ops::DerefMut
28
+ /// [`Borrow`]: core::borrow::Borrow
29
+ /// [`BorrowMut`]: core::borrow::BorrowMut
30
+ ///
31
+ ///
32
+ /// # Safety
33
+ ///
34
+ /// The specified inheritance chain must be correct (including in the correct
35
+ /// order), and the types in said chain must be valid as Objective-C objects -
36
+ /// this is easiest to ensure by also creating those using this macro.
37
+ ///
38
+ ///
39
+ /// # Example
40
+ ///
41
+ /// Create a new type to represent the `NSFormatter` class.
42
+ ///
43
+ /// ```
44
+ /// use objc2::msg_send_id;
45
+ /// use objc2::rc::{Id, Shared};
46
+ /// use objc2_foundation::{object, NSObject};
47
+ /// #
48
+ /// # #[cfg(feature = "gnustep-1-7")]
49
+ /// # unsafe { objc2::__gnustep_hack::get_class_to_force_linkage() };
50
+ ///
51
+ /// object! {
52
+ /// /// An example description.
53
+ /// #[derive(PartialEq, Eq, Hash)] // Uses `NSObject`'s implementation
54
+ /// // Specify class and superclass
55
+ /// // In this case the class `NSFormatter`, which subclasses `NSObject`
56
+ /// unsafe pub struct NSFormatter: NSObject;
57
+ /// }
58
+ ///
59
+ /// // Provided by the macro
60
+ /// let cls = NSFormatter::class();
61
+ ///
62
+ /// // `NSFormatter` implements `Message`:
63
+ /// let obj: Id<NSFormatter, Shared> = unsafe { msg_send_id![cls, new].unwrap() };
64
+ /// ```
65
+ ///
66
+ /// Represent the `NSDateFormatter` class, using the `NSFormatter` type we
67
+ /// declared previously to specify as its superclass.
68
+ ///
69
+ /// ```
70
+ /// use objc2_foundation::{object, NSObject};
71
+ /// #
72
+ /// # object! {
73
+ /// # #[derive(PartialEq, Eq, Hash)]
74
+ /// # unsafe pub struct NSFormatter: NSObject;
75
+ /// # }
76
+ ///
77
+ /// object! {
78
+ /// #[derive(PartialEq, Eq, Hash)]
79
+ /// // Specify the correct inheritance chain
80
+ /// // `NSDateFormatter` subclasses `NSFormatter` which subclasses `NSObject`
81
+ /// unsafe pub struct NSDateFormatter: NSFormatter, NSObject;
82
+ /// }
83
+ /// ```
84
+ ///
85
+ /// See the source code of `objc2_foundation` in general for more examples.
86
+ #[ macro_export]
87
+ macro_rules! object {
88
+ (
89
+ $( #[ $m: meta] ) *
90
+ unsafe $v: vis struct $name: ident: $( $inheritance_chain: ty) ,+;
91
+ ) => {
92
+ $crate:: __inner_object! {
93
+ @__inner
94
+ $( #[ $m] ) *
95
+ unsafe $v struct $name<>: $( $inheritance_chain, ) + $crate:: objc2:: runtime:: Object { }
96
+ }
97
+ } ;
98
+ }
99
+
100
+ #[ doc( hidden) ]
101
+ #[ macro_export]
1
102
macro_rules! __impl_as_ref_borrow {
2
103
( $name: ident<$( $t: ident $( : $b: ident) ?) ,* >, ) => { } ;
3
104
( $name: ident<$( $t: ident $( : $b: ident) ?) ,* >, $item: ty, $( $tail: ty, ) * ) => {
4
- impl <$( $t $( : $b) ?) ,* > AsRef <$item> for $name<$( $t) ,* > {
105
+ impl <$( $t $( : $b) ?) ,* > $crate :: __core :: convert :: AsRef <$item> for $name<$( $t) ,* > {
5
106
#[ inline]
6
107
fn as_ref( & self ) -> & $item {
7
108
// Triggers Deref coercion depending on return type
8
109
& * self
9
110
}
10
111
}
11
112
12
- impl <$( $t $( : $b) ?) ,* > AsMut <$item> for $name<$( $t) ,* > {
113
+ impl <$( $t $( : $b) ?) ,* > $crate :: __core :: convert :: AsMut <$item> for $name<$( $t) ,* > {
13
114
#[ inline]
14
115
fn as_mut( & mut self ) -> & mut $item {
15
116
// Triggers DerefMut coercion depending on return type
@@ -23,55 +124,40 @@ macro_rules! __impl_as_ref_borrow {
23
124
// In particular, `Eq`, `Ord` and `Hash` all give the same results
24
125
// after borrow.
25
126
26
- impl <$( $t $( : $b) ?) ,* > :: core :: borrow:: Borrow <$item> for $name<$( $t) ,* > {
127
+ impl <$( $t $( : $b) ?) ,* > $crate :: __core :: borrow:: Borrow <$item> for $name<$( $t) ,* > {
27
128
#[ inline]
28
129
fn borrow( & self ) -> & $item {
29
130
// Triggers Deref coercion depending on return type
30
131
& * self
31
132
}
32
133
}
33
134
34
- impl <$( $t $( : $b) ?) ,* > :: core :: borrow:: BorrowMut <$item> for $name<$( $t) ,* > {
135
+ impl <$( $t $( : $b) ?) ,* > $crate :: __core :: borrow:: BorrowMut <$item> for $name<$( $t) ,* > {
35
136
#[ inline]
36
137
fn borrow_mut( & mut self ) -> & mut $item {
37
138
// Triggers Deref coercion depending on return type
38
139
& mut * self
39
140
}
40
141
}
41
142
42
- __impl_as_ref_borrow!( $name<$( $t $( : $b) ?) ,* >, $( $tail, ) * ) ;
143
+ $crate :: __impl_as_ref_borrow!( $name<$( $t $( : $b) ?) ,* >, $( $tail, ) * ) ;
43
144
} ;
44
145
}
45
146
46
- /// TODO
47
- ///
48
- /// # Safety
49
- ///
50
- /// The given name must be a valid Objective-C class that inherits NSObject
51
- /// and it's instances must have the raw encoding `Encoding::Object` (an
52
- /// example: `NSAutoreleasePool` does not have this). Finally the ownership
53
- /// must be correct for this class.
54
- macro_rules! object {
55
- (
56
- $( #[ $m: meta] ) *
57
- unsafe $v: vis struct $name: ident: $( $inheritance_chain: ty) ,+ $( ; ) ?
58
- ) => {
59
- object! {
60
- @__inner
61
- $( #[ $m] ) *
62
- unsafe $v struct $name<>: $( $inheritance_chain, ) + :: objc2:: runtime:: Object { }
63
- }
64
- } ;
147
+ #[ doc( hidden) ]
148
+ #[ macro_export]
149
+ macro_rules! __inner_object {
150
+ // TODO: Expose this variant in the `object` macro.
65
151
(
66
152
$( #[ $m: meta] ) *
67
153
unsafe $v: vis struct $name: ident<$( $t: ident $( : $b: ident) ?) ,* >: $( $inheritance_chain: ty) ,+ {
68
154
$( $p: ident: $pty: ty, ) *
69
155
}
70
156
) => {
71
- object ! {
157
+ $crate :: __inner_object ! {
72
158
@__inner
73
159
$( #[ $m] ) *
74
- unsafe $v struct $name<$( $t $( : $b) ?) ,* >: $( $inheritance_chain, ) + :: objc2:: runtime:: Object {
160
+ unsafe $v struct $name<$( $t $( : $b) ?) ,* >: $( $inheritance_chain, ) + $crate :: objc2:: runtime:: Object {
75
161
$( $p: $pty, ) *
76
162
}
77
163
}
@@ -87,20 +173,21 @@ macro_rules! object {
87
173
// TODO: repr(transparent) when the inner pointer is no longer a ZST.
88
174
#[ repr( C ) ]
89
175
$v struct $name<$( $t $( : $b) ?) ,* > {
90
- inner : $inherits,
176
+ __inner : $inherits,
91
177
// Additional fields (should only be zero-sized PhantomData).
92
178
$( $p: $pty) ,*
93
179
}
94
180
95
- unsafe impl <$( $t $( : $b) ?) ,* > :: objc2:: Message for $name<$( $t) ,* > { }
181
+ unsafe impl <$( $t $( : $b) ?) ,* > $crate :: objc2:: Message for $name<$( $t) ,* > { }
96
182
97
- unsafe impl <$( $t $( : $b) ?) ,* > :: objc2:: RefEncode for $name<$( $t) ,* > {
98
- const ENCODING_REF : :: objc2:: Encoding <' static > = :: objc2:: Encoding :: Object ;
183
+ unsafe impl <$( $t $( : $b) ?) ,* > $crate:: objc2:: RefEncode for $name<$( $t) ,* > {
184
+ const ENCODING_REF : $crate:: objc2:: Encoding <' static >
185
+ = <$inherits as $crate:: objc2:: RefEncode >:: ENCODING_REF ;
99
186
}
100
187
101
188
impl <$( $t $( : $b) ?) ,* > $name<$( $t) ,* > {
102
- $v fn class( ) -> & ' static :: objc2:: runtime:: Class {
103
- :: objc2:: class!( $name)
189
+ $v fn class( ) -> & ' static $crate :: objc2:: runtime:: Class {
190
+ $crate :: objc2:: class!( $name)
104
191
}
105
192
}
106
193
@@ -122,12 +209,12 @@ macro_rules! object {
122
209
// Note that you can easily have two different variables pointing to
123
210
// the same object, `x: &T` and `y: &T::Target`, and this would be
124
211
// perfectly safe!
125
- impl <$( $t $( : $b) ?) ,* > :: core :: ops:: Deref for $name<$( $t) ,* > {
212
+ impl <$( $t $( : $b) ?) ,* > $crate :: __core :: ops:: Deref for $name<$( $t) ,* > {
126
213
type Target = $inherits;
127
214
128
215
#[ inline]
129
216
fn deref( & self ) -> & Self :: Target {
130
- & self . inner
217
+ & self . __inner
131
218
}
132
219
}
133
220
@@ -142,28 +229,28 @@ macro_rules! object {
142
229
// But `&mut NSMutableString` -> `&mut NSString` safe, since the
143
230
// `NSCopying` implementation of `NSMutableString` is used, and that
144
231
// is guaranteed to return a different object.
145
- impl <$( $t $( : $b) ?) ,* > :: core :: ops:: DerefMut for $name<$( $t) ,* > {
232
+ impl <$( $t $( : $b) ?) ,* > $crate :: __core :: ops:: DerefMut for $name<$( $t) ,* > {
146
233
#[ inline]
147
234
fn deref_mut( & mut self ) -> & mut Self :: Target {
148
- & mut self . inner
235
+ & mut self . __inner
149
236
}
150
237
}
151
238
152
- impl <$( $t $( : $b) ?) ,* > AsRef <Self > for $name<$( $t) ,* > {
239
+ impl <$( $t $( : $b) ?) ,* > $crate :: __core :: convert :: AsRef <Self > for $name<$( $t) ,* > {
153
240
#[ inline]
154
241
fn as_ref( & self ) -> & Self {
155
242
self
156
243
}
157
244
}
158
245
159
- impl <$( $t $( : $b) ?) ,* > AsMut <Self > for $name<$( $t) ,* > {
246
+ impl <$( $t $( : $b) ?) ,* > $crate :: __core :: convert :: AsMut <Self > for $name<$( $t) ,* > {
160
247
#[ inline]
161
248
fn as_mut( & mut self ) -> & mut Self {
162
249
self
163
250
}
164
251
}
165
252
166
- __impl_as_ref_borrow!( $name<$( $t $( : $b) ?) ,* >, $inherits, $( $inheritance_rest, ) * ) ;
253
+ $crate :: __impl_as_ref_borrow!( $name<$( $t $( : $b) ?) ,* >, $inherits, $( $inheritance_rest, ) * ) ;
167
254
} ;
168
255
}
169
256
@@ -175,7 +262,7 @@ macro_rules! unsafe_def_fn {
175
262
$( #[ $m] ) *
176
263
$v fn new( ) -> Id <Self , $o> {
177
264
let cls = Self :: class( ) ;
178
- unsafe { :: objc2:: msg_send_id![ cls, new] . unwrap( ) }
265
+ unsafe { $crate :: objc2:: msg_send_id![ cls, new] . unwrap( ) }
179
266
}
180
267
} ;
181
268
}
0 commit comments