Skip to content

Commit 54be2ce

Browse files
authored
Merge pull request #237 from madsmtm/macro-syntax
Change `extern_class!` and `declare_class!` macro syntax
2 parents b97bcbb + 0949941 commit 54be2ce

30 files changed

+642
-347
lines changed

objc2/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
2222
* Added `Id::into_superclass`.
2323

2424
### Changed
25-
* **BREAKING**: Change selector syntax in `declare_class!` macro to be more Rust-like.
25+
* **BREAKING**: Change syntax in `extern_class!` macro to be more Rust-like.
26+
* **BREAKING**: Change syntax in `declare_class!` macro to be more Rust-like.
2627
* **BREAKING**: Renamed `Id::from_owned` to `Id::into_shared`.
2728

2829

objc2/examples/delegate.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,30 @@ use objc2::{declare_class, extern_class, msg_send, msg_send_id, ClassType};
99
extern "C" {}
1010

1111
#[cfg(all(feature = "apple", target_os = "macos"))]
12-
extern_class! {
13-
unsafe struct NSResponder: NSObject;
14-
}
12+
extern_class!(
13+
struct NSResponder;
14+
15+
unsafe impl ClassType for NSResponder {
16+
type Superclass = NSObject;
17+
}
18+
);
1519

1620
#[cfg(all(feature = "apple", target_os = "macos"))]
17-
declare_class! {
18-
unsafe struct CustomAppDelegate: NSResponder, NSObject {
21+
declare_class!(
22+
struct CustomAppDelegate {
1923
pub ivar: u8,
2024
another_ivar: Bool,
2125
}
2226

23-
unsafe impl {
27+
unsafe impl ClassType for CustomAppDelegate {
28+
#[inherits(NSObject)]
29+
type Superclass = NSResponder;
30+
}
31+
32+
unsafe impl CustomAppDelegate {
2433
#[sel(initWith:another:)]
25-
fn init_with(
26-
self: &mut Self,
27-
ivar: u8,
28-
another_ivar: Bool,
29-
) -> *mut Self {
30-
let this: *mut Self = unsafe {
31-
msg_send![super(self, NSResponder::class()), init]
32-
};
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] };
3336
if let Some(this) = unsafe { this.as_mut() } {
3437
// TODO: Allow initialization through MaybeUninit
3538
*this.ivar = ivar;
@@ -49,7 +52,7 @@ declare_class! {
4952
// `clang` only when used in Objective-C...
5053
//
5154
// TODO: Investigate this!
52-
unsafe impl {
55+
unsafe impl CustomAppDelegate {
5356
/// This is `unsafe` because it expects `sender` to be valid
5457
#[sel(applicationDidFinishLaunching:)]
5558
unsafe fn did_finish_launching(&self, sender: *mut Object) {
@@ -65,7 +68,7 @@ declare_class! {
6568
println!("Will terminate!");
6669
}
6770
}
68-
}
71+
);
6972

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

objc2/examples/nspasteboard.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@ extern "C" {
2222
}
2323

2424
#[cfg(all(feature = "apple", target_os = "macos"))]
25-
extern_class! {
25+
extern_class!(
2626
/// <https://developer.apple.com/documentation/appkit/nspasteboard?language=objc>
27+
pub struct NSPasteboard;
28+
2729
// SAFETY: NSPasteboard actually inherits from NSObject.
28-
unsafe pub struct NSPasteboard: NSObject;
29-
}
30+
unsafe impl ClassType for NSPasteboard {
31+
type Superclass = NSObject;
32+
}
33+
);
3034

3135
#[cfg(all(feature = "apple", target_os = "macos"))]
3236
impl NSPasteboard {

objc2/examples/speech_synthethis.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@ mod appkit {
2626
#[link(name = "AppKit", kind = "framework")]
2727
extern "C" {}
2828

29-
extern_class! {
29+
extern_class!(
3030
/// <https://developer.apple.com/documentation/appkit/nsspeechsynthesizer?language=objc>
31-
unsafe pub struct NSSpeechSynthesizer: NSObject;
32-
}
31+
pub struct NSSpeechSynthesizer;
32+
33+
unsafe impl ClassType for NSSpeechSynthesizer {
34+
type Superclass = NSObject;
35+
}
36+
);
3337

3438
impl NSSpeechSynthesizer {
3539
// Uses default voice
@@ -100,11 +104,15 @@ mod avfaudio {
100104
#[link(name = "AVFoundation", kind = "framework")]
101105
extern "C" {}
102106

103-
extern_class! {
107+
extern_class!(
104108
/// <https://developer.apple.com/documentation/avfaudio/avspeechsynthesizer?language=objc>
105109
#[derive(Debug)]
106-
unsafe pub struct AVSpeechSynthesizer: NSObject;
107-
}
110+
pub struct AVSpeechSynthesizer;
111+
112+
unsafe impl ClassType for AVSpeechSynthesizer {
113+
type Superclass = NSObject;
114+
}
115+
);
108116

109117
impl AVSpeechSynthesizer {
110118
pub fn new() -> Id<Self, Owned> {
@@ -122,11 +130,15 @@ mod avfaudio {
122130
}
123131
}
124132

125-
extern_class! {
133+
extern_class!(
126134
/// <https://developer.apple.com/documentation/avfaudio/avspeechutterance?language=objc>
127135
#[derive(Debug)]
128-
unsafe pub struct AVSpeechUtterance: NSObject;
129-
}
136+
pub struct AVSpeechUtterance;
137+
138+
unsafe impl ClassType for AVSpeechUtterance {
139+
type Superclass = NSObject;
140+
}
141+
);
130142

131143
impl AVSpeechUtterance {
132144
pub fn new(string: &NSString) -> Id<Self, Owned> {

objc2/src/__macro_helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ pub const fn in_selector_family(mut selector: &[u8], mut family: &[u8]) -> bool
180180
// Skip leading underscores from selector
181181
loop {
182182
selector = match selector {
183-
[b'_', selector @ ..] => (selector),
183+
[b'_', rest @ ..] => rest,
184184
_ => break,
185185
}
186186
}

objc2/src/class_type.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ use crate::Message;
4444
/// ```ignore
4545
/// use objc2::{extern_class, ClassType};
4646
///
47-
/// extern_class! {
48-
/// unsafe struct MyClass: NSObject;
49-
/// }
47+
/// extern_class!(
48+
/// struct MyClass;
49+
///
50+
/// unsafe impl ClassType for MyClass {
51+
/// type Superclass = NSObject;
52+
/// }
53+
/// );
5054
///
5155
/// let cls = MyClass::class();
5256
/// ```

objc2/src/foundation/array.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::rc::{DefaultId, Id, Owned, Ownership, Shared, SliceId};
1212
use crate::runtime::{Class, Object};
1313
use crate::{ClassType, Message, __inner_extern_class, msg_send, msg_send_id};
1414

15-
__inner_extern_class! {
15+
__inner_extern_class!(
1616
/// An immutable ordered collection of objects.
1717
///
1818
/// This is the Objective-C equivalent of a "boxed slice" (`Box<[T]>`),
@@ -52,11 +52,15 @@ __inner_extern_class! {
5252
// `T: PartialEq` bound correct because `NSArray` does deep (instead of
5353
// shallow) equality comparisons.
5454
#[derive(PartialEq, Eq, Hash)]
55-
unsafe pub struct NSArray<T: Message, O: Ownership = Shared>: NSObject {
55+
pub struct NSArray<T: Message, O: Ownership = Shared> {
5656
item: PhantomData<Id<T, O>>,
5757
notunwindsafe: PhantomData<&'static mut ()>,
5858
}
59-
}
59+
60+
unsafe impl<T: Message, O: Ownership> ClassType for NSArray<T, O> {
61+
type Superclass = NSObject;
62+
}
63+
);
6064

6165
// SAFETY: Same as Id<T, O> (which is what NSArray effectively stores).
6266
unsafe impl<T: Message + Sync + Send> Sync for NSArray<T, Shared> {}

objc2/src/foundation/attributed_string.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::rc::{DefaultId, Id, Shared};
88
use crate::runtime::Object;
99
use crate::{extern_class, msg_send, msg_send_id, ClassType};
1010

11-
extern_class! {
11+
extern_class!(
1212
/// A string that has associated attributes for portions of its text.
1313
///
1414
/// Examples of attributes could be: Visual style, hyperlinks, or
@@ -22,8 +22,12 @@ extern_class! {
2222
///
2323
/// See [Apple's documentation](https://developer.apple.com/documentation/foundation/nsattributedstring?language=objc).
2424
#[derive(PartialEq, Eq, Hash)]
25-
unsafe pub struct NSAttributedString: NSObject;
26-
}
25+
pub struct NSAttributedString;
26+
27+
unsafe impl ClassType for NSAttributedString {
28+
type Superclass = NSObject;
29+
}
30+
);
2731

2832
// SAFETY: `NSAttributedString` is immutable and `NSMutableAttributedString`
2933
// can only be mutated from `&mut` methods.

objc2/src/foundation/data.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,19 @@ use crate::rc::{DefaultId, Id, Shared};
1111
use crate::runtime::{Class, Object};
1212
use crate::{extern_class, msg_send, msg_send_id, ClassType};
1313

14-
extern_class! {
14+
extern_class!(
1515
/// A static byte buffer in memory.
1616
///
1717
/// This is similar to a [`slice`][`prim@slice`] of [`u8`].
1818
///
1919
/// See [Apple's documentation](https://developer.apple.com/documentation/foundation/nsdata?language=objc).
2020
#[derive(PartialEq, Eq, Hash)]
21-
unsafe pub struct NSData: NSObject;
22-
}
21+
pub struct NSData;
22+
23+
unsafe impl ClassType for NSData {
24+
type Superclass = NSObject;
25+
}
26+
);
2327

2428
// SAFETY: `NSData` is immutable and `NSMutableData` can only be mutated from
2529
// `&mut` methods.

objc2/src/foundation/dictionary.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ use super::{NSArray, NSCopying, NSEnumerator, NSFastEnumeration, NSObject};
1010
use crate::rc::{DefaultId, Id, Owned, Shared, SliceId};
1111
use crate::{ClassType, __inner_extern_class, msg_send, msg_send_id, Message};
1212

13-
__inner_extern_class! {
13+
__inner_extern_class!(
1414
#[derive(PartialEq, Eq, Hash)]
15-
unsafe pub struct NSDictionary<K: Message, V: Message>: NSObject {
15+
pub struct NSDictionary<K: Message, V: Message> {
1616
key: PhantomData<Id<K, Shared>>,
1717
obj: PhantomData<Id<V, Owned>>,
1818
}
19-
}
19+
20+
unsafe impl<K: Message, V: Message> ClassType for NSDictionary<K, V> {
21+
type Superclass = NSObject;
22+
}
23+
);
2024

2125
// TODO: SAFETY
2226
// Approximately same as `NSArray<T, Shared>`

objc2/src/foundation/error.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::ffi::NSInteger;
66
use crate::rc::{Id, Shared};
77
use crate::{extern_class, msg_send, msg_send_id, ClassType};
88

9-
extern_class! {
9+
extern_class!(
1010
/// Information about an error condition including a domain, a
1111
/// domain-specific error code, and application-specific information.
1212
///
@@ -16,8 +16,12 @@ extern_class! {
1616
/// [err]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorHandling/ErrorHandling.html#//apple_ref/doc/uid/TP40001806-CH201-SW1
1717
/// [api]: https://developer.apple.com/documentation/foundation/nserror?language=objc
1818
#[derive(PartialEq, Eq, Hash)]
19-
unsafe pub struct NSError: NSObject;
20-
}
19+
pub struct NSError;
20+
21+
unsafe impl ClassType for NSError {
22+
type Superclass = NSObject;
23+
}
24+
);
2125

2226
// SAFETY: Error objects are immutable data containers.
2327
unsafe impl Sync for NSError {}

objc2/src/foundation/exception.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::rc::{Id, Shared};
88
use crate::runtime::Object;
99
use crate::{extern_class, msg_send, msg_send_id, sel, ClassType};
1010

11-
extern_class! {
11+
extern_class!(
1212
/// A special condition that interrupts the normal flow of program
1313
/// execution.
1414
///
@@ -19,8 +19,12 @@ extern_class! {
1919
///
2020
/// [doc]: https://developer.apple.com/documentation/foundation/nsexception?language=objc
2121
#[derive(PartialEq, Eq, Hash)]
22-
unsafe pub struct NSException: NSObject;
23-
}
22+
pub struct NSException;
23+
24+
unsafe impl ClassType for NSException {
25+
type Superclass = NSObject;
26+
}
27+
);
2428

2529
// SAFETY: Exception objects are immutable data containers, and documented as
2630
// thread safe.

objc2/src/foundation/mutable_array.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,23 @@ use super::{
1313
use crate::rc::{DefaultId, Id, Owned, Ownership, Shared, SliceId};
1414
use crate::{ClassType, Message, __inner_extern_class, msg_send, msg_send_id};
1515

16-
__inner_extern_class! {
16+
__inner_extern_class!(
1717
/// A growable ordered collection of objects.
1818
///
1919
/// See the documentation for [`NSArray`] and/or [Apple's
2020
/// documentation][apple-doc] for more information.
2121
///
2222
/// [apple-doc]: https://developer.apple.com/documentation/foundation/nsmutablearray?language=objc
2323
#[derive(PartialEq, Eq, Hash)]
24-
unsafe pub struct NSMutableArray<T: Message, O: Ownership = Owned>: NSArray<T, O>, NSObject {
24+
pub struct NSMutableArray<T: Message, O: Ownership = Owned> {
2525
p: PhantomData<*mut ()>,
2626
}
27-
}
27+
28+
unsafe impl<T: Message, O: Ownership> ClassType for NSMutableArray<T, O> {
29+
#[inherits(NSObject)]
30+
type Superclass = NSArray<T, O>;
31+
}
32+
);
2833

2934
// SAFETY: Same as NSArray<T, O>
3035
//

objc2/src/foundation/mutable_attributed_string.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@ use super::{NSAttributedString, NSCopying, NSMutableCopying, NSObject, NSString}
44
use crate::rc::{DefaultId, Id, Owned, Shared};
55
use crate::{extern_class, msg_send, msg_send_id, ClassType};
66

7-
extern_class! {
7+
extern_class!(
88
/// A mutable string that has associated attributes.
99
///
1010
/// See [Apple's documentation](https://developer.apple.com/documentation/foundation/nsmutableattributedstring?language=objc).
1111
#[derive(PartialEq, Eq, Hash)]
12-
unsafe pub struct NSMutableAttributedString: NSAttributedString, NSObject;
13-
}
12+
pub struct NSMutableAttributedString;
13+
14+
unsafe impl ClassType for NSMutableAttributedString {
15+
#[inherits(NSObject)]
16+
type Superclass = NSAttributedString;
17+
}
18+
);
1419

1520
/// Creating mutable attributed strings.
1621
impl NSMutableAttributedString {

objc2/src/foundation/mutable_data.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use super::{NSCopying, NSData, NSMutableCopying, NSObject, NSRange};
1111
use crate::rc::{DefaultId, Id, Owned, Shared};
1212
use crate::{extern_class, msg_send, msg_send_id, ClassType};
1313

14-
extern_class! {
14+
extern_class!(
1515
/// A dynamic byte buffer in memory.
1616
///
1717
/// This is the Objective-C equivalent of a [`Vec`] containing [`u8`].
@@ -20,8 +20,13 @@ extern_class! {
2020
///
2121
/// [`Vec`]: std::vec::Vec
2222
#[derive(PartialEq, Eq, Hash)]
23-
unsafe pub struct NSMutableData: NSData, NSObject;
24-
}
23+
pub struct NSMutableData;
24+
25+
unsafe impl ClassType for NSMutableData {
26+
#[inherits(NSObject)]
27+
type Superclass = NSData;
28+
}
29+
);
2530

2631
/// Creation methods
2732
impl NSMutableData {

0 commit comments

Comments
 (0)