Skip to content

Commit 0949941

Browse files
committed
Change syntax of impls in declare_class! macro
Leads to a bit more duplication, but means the syntax is now Rust-like and can be formatted by rustfmt!
1 parent 87c6016 commit 0949941

3 files changed

Lines changed: 141 additions & 58 deletions

File tree

objc2/examples/delegate.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ extern_class!(
1818
);
1919

2020
#[cfg(all(feature = "apple", target_os = "macos"))]
21-
declare_class! {
21+
declare_class!(
2222
struct CustomAppDelegate {
2323
pub ivar: u8,
2424
another_ivar: Bool,
@@ -29,16 +29,10 @@ declare_class! {
2929
type Superclass = NSResponder;
3030
}
3131

32-
unsafe impl {
32+
unsafe impl CustomAppDelegate {
3333
#[sel(initWith:another:)]
34-
fn init_with(
35-
self: &mut Self,
36-
ivar: u8,
37-
another_ivar: Bool,
38-
) -> *mut Self {
39-
let this: *mut Self = unsafe {
40-
msg_send![super(self, NSResponder::class()), init]
41-
};
34+
fn init_with(self: &mut Self, ivar: u8, another_ivar: Bool) -> *mut Self {
35+
let this: *mut Self = unsafe { msg_send![super(self, NSResponder::class()), init] };
4236
if let Some(this) = unsafe { this.as_mut() } {
4337
// TODO: Allow initialization through MaybeUninit
4438
*this.ivar = ivar;
@@ -58,7 +52,7 @@ declare_class! {
5852
// `clang` only when used in Objective-C...
5953
//
6054
// TODO: Investigate this!
61-
unsafe impl {
55+
unsafe impl CustomAppDelegate {
6256
/// This is `unsafe` because it expects `sender` to be valid
6357
#[sel(applicationDidFinishLaunching:)]
6458
unsafe fn did_finish_launching(&self, sender: *mut Object) {
@@ -74,7 +68,7 @@ declare_class! {
7468
println!("Will terminate!");
7569
}
7670
}
77-
}
71+
);
7872

7973
#[cfg(all(feature = "apple", target_os = "macos"))]
8074
impl CustomAppDelegate {

objc2/src/macros/declare_class.rs

Lines changed: 132 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,13 @@ macro_rules! __inner_declare_class {
210210
/// either be able to be created using [`MaybeUninit::zeroed`], or be
211211
/// properly initialized in an `init` method.
212212
///
213-
/// `unsafe impl { ... }` asserts that the types match those that are expected
214-
/// when the method is invoked from Objective-C. Note that there are no
215-
/// safe-guards here; you can easily write `i8`, but if Objective-C thinks
213+
/// `unsafe impl T { ... }` asserts that the types match those that are
214+
/// expected when the method is invoked from Objective-C. Note that there are
215+
/// no safe-guards here; you can easily write `i8`, but if Objective-C thinks
216216
/// it's an `u32`, it will cause UB when called!
217217
///
218-
/// `unsafe impl protocol ... { ... }` requires that all required methods of
219-
/// the specified protocol is implemented, and that any extra requirements
218+
/// `unsafe impl Protocol<P> for T { ... }` requires that all required methods
219+
/// of the specified protocol is implemented, and that any extra requirements
220220
/// (implicit or explicit) that the protocol has are upheld. The methods in
221221
/// this definition has the same safety requirements as above.
222222
///
@@ -238,7 +238,7 @@ macro_rules! __inner_declare_class {
238238
/// # #[cfg(feature = "gnustep-1-7")]
239239
/// # unsafe { objc2::__gnustep_hack::get_class_to_force_linkage() };
240240
///
241-
/// declare_class! {
241+
/// declare_class!(
242242
/// struct MyCustomObject {
243243
/// foo: u8,
244244
/// pub bar: c_int,
@@ -248,7 +248,7 @@ macro_rules! __inner_declare_class {
248248
/// type Superclass = NSObject;
249249
/// }
250250
///
251-
/// unsafe impl {
251+
/// unsafe impl MyCustomObject {
252252
/// #[sel(initWithFoo:)]
253253
/// fn init_with(&mut self, foo: u8) -> Option<&mut Self> {
254254
/// let this: Option<&mut Self> = unsafe {
@@ -275,15 +275,15 @@ macro_rules! __inner_declare_class {
275275
/// }
276276
/// }
277277
///
278-
/// unsafe impl protocol NSCopying {
278+
/// unsafe impl Protocol<NSCopying> for MyCustomObject {
279279
/// #[sel(copyWithZone:)]
280280
/// fn copy_with_zone(&self, _zone: *const NSZone) -> *mut Self {
281281
/// let mut obj = Self::new(*self.foo);
282282
/// *obj.bar = *self.bar;
283283
/// obj.autorelease_return()
284284
/// }
285285
/// }
286-
/// }
286+
/// );
287287
///
288288
/// impl MyCustomObject {
289289
/// pub fn new(foo: u8) -> Id<Self, Owned> {
@@ -385,12 +385,7 @@ macro_rules! declare_class {
385385
type Superclass = $superclass:ty;
386386
}
387387

388-
$(
389-
$(#[$impl_m:meta])*
390-
unsafe impl $(protocol $protocol:ident)? {
391-
$($methods:tt)*
392-
}
393-
)*
388+
$($methods:tt)*
394389
} => {
395390
$(
396391
#[allow(non_camel_case_types)]
@@ -446,24 +441,11 @@ macro_rules! declare_class {
446441
builder.add_static_ivar::<$ivar>();
447442
)*
448443

449-
$(
450-
// Implement protocol if any specified
451-
$(
452-
let err_str = concat!("could not find protocol ", stringify!($protocol));
453-
builder.add_protocol($crate::runtime::Protocol::get(stringify!($protocol)).expect(err_str));
454-
)?
455-
456-
// Implement methods
457-
// SAFETY: Upheld by caller
458-
unsafe {
459-
$crate::__inner_declare_class! {
460-
@rewrite_methods
461-
@(register_out(builder))
462-
463-
$($methods)*
464-
}
465-
}
466-
)*
444+
// Implement protocols and methods
445+
$crate::__declare_class_methods!(
446+
@register_out(builder)
447+
$($methods)*
448+
);
467449

468450
let _cls = builder.register();
469451
});
@@ -474,16 +456,123 @@ macro_rules! declare_class {
474456
}
475457

476458
// Methods
477-
$(
478-
$(#[$impl_m])*
479-
impl $name {
480-
$crate::__inner_declare_class! {
481-
@rewrite_methods
482-
@(method_out)
483-
484-
$($methods)*
485-
}
459+
$crate::__declare_class_methods!(
460+
@method_out
461+
$($methods)*
462+
);
463+
};
464+
}
465+
466+
#[doc(hidden)]
467+
#[macro_export]
468+
macro_rules! __declare_class_methods {
469+
(@method_out) => {};
470+
// With protocol
471+
(
472+
@method_out
473+
474+
$(#[$m:meta])*
475+
unsafe impl Protocol<$protocol:ident> for $for:ty {
476+
$($methods:tt)*
477+
}
478+
479+
$($rest:tt)*
480+
) => {
481+
$(#[$m])*
482+
impl $for {
483+
$crate::__inner_declare_class! {
484+
@rewrite_methods
485+
@(method_out)
486+
$($methods)*
486487
}
487-
)*
488+
}
489+
490+
$crate::__declare_class_methods!(
491+
@method_out
492+
$($rest)*
493+
);
494+
};
495+
// Without protocol
496+
(
497+
@method_out
498+
499+
$(#[$m:meta])*
500+
unsafe impl $for:ty {
501+
$($methods:tt)*
502+
}
503+
504+
$($rest:tt)*
505+
) => {
506+
$(#[$m])*
507+
impl $for {
508+
$crate::__inner_declare_class! {
509+
@rewrite_methods
510+
@(method_out)
511+
$($methods)*
512+
}
513+
}
514+
515+
$crate::__declare_class_methods!(
516+
@method_out
517+
$($rest)*
518+
);
519+
};
520+
521+
(@register_out($builder:ident)) => {};
522+
// With protocol
523+
(
524+
@register_out($builder:ident)
525+
526+
$(#[$m:meta])*
527+
unsafe impl Protocol<$protocol:ident> for $for:ty {
528+
$($methods:tt)*
529+
}
530+
531+
$($rest:tt)*
532+
) => {
533+
// Implement protocol
534+
let err_str = concat!("could not find protocol ", stringify!($protocol));
535+
$builder.add_protocol($crate::runtime::Protocol::get(stringify!($protocol)).expect(err_str));
536+
537+
// SAFETY: Upheld by caller
538+
unsafe {
539+
$crate::__inner_declare_class! {
540+
@rewrite_methods
541+
@(register_out($builder))
542+
543+
$($methods)*
544+
}
545+
}
546+
547+
$crate::__declare_class_methods!(
548+
@register_out($builder)
549+
$($rest)*
550+
);
551+
};
552+
// Without protocol
553+
(
554+
@register_out($builder:ident)
555+
556+
$(#[$m:meta])*
557+
unsafe impl $for:ty {
558+
$($methods:tt)*
559+
}
560+
561+
$($rest:tt)*
562+
) => {
563+
// SAFETY: Upheld by caller
564+
unsafe {
565+
$crate::__inner_declare_class! {
566+
@rewrite_methods
567+
@(register_out($builder))
568+
569+
$($methods)*
570+
}
571+
}
572+
573+
$crate::__declare_class_methods!(
574+
@register_out($builder)
575+
$($rest)*
576+
);
488577
};
489578
}

objc2/src/rc/test_object.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ std::thread_local! {
4848
pub(crate) static TEST_DATA: RefCell<ThreadTestData> = RefCell::new(Default::default());
4949
}
5050

51-
declare_class! {
51+
declare_class!(
5252
/// A helper object that counts how many times various reference-counting
5353
/// primitives are called.
5454
#[derive(Debug, PartialEq)]
@@ -58,7 +58,7 @@ declare_class! {
5858
type Superclass = NSObject;
5959
}
6060

61-
unsafe impl {
61+
unsafe impl RcTestObject {
6262
#[sel(alloc)]
6363
fn alloc() -> *mut Self {
6464
TEST_DATA.with(|data| data.borrow_mut().alloc += 1);
@@ -127,7 +127,7 @@ declare_class! {
127127
Id::consume_as_ptr(ManuallyDrop::new(Self::new()))
128128
}
129129
}
130-
}
130+
);
131131

132132
unsafe impl Send for RcTestObject {}
133133
unsafe impl Sync for RcTestObject {}

0 commit comments

Comments
 (0)