Skip to content

Commit 893e04f

Browse files
committed
Add more NSUUID functionality
1 parent b76694f commit 893e04f

File tree

3 files changed

+68
-8
lines changed

3 files changed

+68
-8
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ jobs:
153153
# Use --no-fail-fast, except with dinghy
154154
TESTARGS: ${{ matrix.dinghy && ' ' || '--no-fail-fast' }} ${{ matrix.test-args }}
155155
SOME_FEATURES: ${{ matrix.features || 'malloc,block,exception' }}
156-
FEATURES: ${{ matrix.features || 'malloc,block,exception,catch-all,verify_message' }}
156+
FEATURES: ${{ matrix.features || 'malloc,block,exception,catch-all,verify_message,uuid' }}
157157
UNSTABLE_FEATURES: ${{ matrix.unstable-features || 'unstable-autoreleasesafe,unstable-c-unwind' }}
158158

159159
runs-on: ${{ matrix.os }}

objc2-foundation/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,12 @@ gnustep-2-1 = ["gnustep-2-0", "objc2/gnustep-2-1", "block2?/gnustep-2-1"]
4040
block2 = { path = "../block2", version = "=0.2.0-alpha.5", default-features = false, optional = true }
4141
objc2 = { path = "../objc2", version = "=0.3.0-beta.1", default-features = false }
4242

43+
# Provides methods to convert between `uuid::Uuid` and `NSUUID`
44+
uuid = { version = "1.1.2", optional = true, default-features = false }
45+
4346
[package.metadata.docs.rs]
4447
default-target = "x86_64-apple-darwin"
45-
features = ["block", "unstable-docsrs"]
48+
features = ["block", "uuid", "unstable-docsrs"]
4649

4750
targets = [
4851
# MacOS

objc2-foundation/src/uuid.rs

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use core::panic::{RefUnwindSafe, UnwindSafe};
22

3+
use objc2::rc::DefaultId;
34
use objc2::rc::{Id, Shared};
45
use objc2::{msg_send, msg_send_id, Encode, Encoding, RefEncode};
56

@@ -10,6 +11,9 @@ extern_class! {
1011
///
1112
/// Can be used to identify types, interfaces, and other items.
1213
///
14+
/// Conversion methods to/from UUIDs from the `uuid` crate can be
15+
/// enabled with the `uuid` crate feature.
16+
///
1317
/// See [Apple's documentation](https://developer.apple.com/documentation/foundation/nsuuid?language=objc).
1418
#[derive(Debug, PartialEq, Eq, Hash)]
1519
unsafe pub struct NSUUID: NSObject;
@@ -35,12 +39,15 @@ impl UnwindSafe for NSUUID {}
3539
impl RefUnwindSafe for NSUUID {}
3640

3741
impl NSUUID {
38-
// TODO: `nil` method?
39-
4042
pub fn new_v4() -> Id<Self, Shared> {
4143
unsafe { msg_send_id![Self::class(), new].unwrap() }
4244
}
4345

46+
/// The 'nil UUID'.
47+
pub fn nil() -> Id<Self, Shared> {
48+
Self::from_bytes([0; 16])
49+
}
50+
4451
pub fn from_bytes(bytes: [u8; 16]) -> Id<Self, Shared> {
4552
let bytes = UuidBytes(bytes);
4653
unsafe {
@@ -49,7 +56,12 @@ impl NSUUID {
4956
}
5057
}
5158

52-
// TODO: `parse_str` using initWithUUIDString:
59+
pub fn from_string(string: &NSString) -> Option<Id<Self, Shared>> {
60+
unsafe {
61+
let obj = msg_send_id![Self::class(), alloc];
62+
msg_send_id![obj, initWithUUIDString: string]
63+
}
64+
}
5365

5466
pub fn as_bytes(&self) -> [u8; 16] {
5567
let mut bytes = UuidBytes([0; 16]);
@@ -58,11 +70,40 @@ impl NSUUID {
5870
}
5971
}
6072

73+
// UUID `compare:` is broken for some reason?
74+
75+
// impl PartialOrd for NSUUID {
76+
// #[inline]
77+
// fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
78+
// Some(self.cmp(other))
79+
// }
80+
// }
81+
82+
// impl Ord for NSUUID {
83+
// fn cmp(&self, other: &Self) -> cmp::Ordering {
84+
// let res: NSComparisonResult = unsafe { msg_send![self, compare: other] };
85+
// res.into()
86+
// }
87+
// }
88+
6189
/// Conversion methods to/from `uuid` crate.
6290
#[cfg(feature = "uuid")]
63-
// TODO: Research how stable the `uuid` crate is (or if we'll have to update
64-
// it constantly).
65-
impl NSUUID {}
91+
impl NSUUID {
92+
pub fn from_uuid(uuid: uuid::Uuid) -> Id<Self, Shared> {
93+
Self::from_bytes(uuid.into_bytes())
94+
}
95+
96+
pub fn as_uuid(&self) -> uuid::Uuid {
97+
uuid::Uuid::from_bytes(self.as_bytes())
98+
}
99+
}
100+
101+
impl DefaultId for NSUUID {
102+
type Ownership = Shared;
103+
fn default_id() -> Id<Self, Self::Ownership> {
104+
Self::nil()
105+
}
106+
}
66107

67108
unsafe impl NSCopying for NSUUID {
68109
type Ownership = Shared;
@@ -92,4 +133,20 @@ mod tests {
92133
let uuid = NSUUID::from_bytes([10; 16]);
93134
assert_eq!(uuid.as_bytes(), [10; 16]);
94135
}
136+
137+
// #[test]
138+
// fn test_compare() {
139+
// let uuid1 = NSUUID::from_bytes([10; 16]);
140+
// let uuid2 = NSUUID::from_bytes([9; 16]);
141+
// assert!(uuid1 > uuid2);
142+
// }
143+
144+
#[cfg(feature = "uuid")]
145+
#[test]
146+
fn test_convert_roundtrip() {
147+
let nsuuid1 = NSUUID::new_v4();
148+
let uuid = nsuuid1.as_uuid();
149+
let nsuuid2 = NSUUID::from_uuid(uuid);
150+
assert_eq!(nsuuid1, nsuuid2);
151+
}
95152
}

0 commit comments

Comments
 (0)