1
1
use core:: panic:: { RefUnwindSafe , UnwindSafe } ;
2
2
3
+ use objc2:: rc:: DefaultId ;
3
4
use objc2:: rc:: { Id , Shared } ;
4
5
use objc2:: { msg_send, msg_send_id, Encode , Encoding , RefEncode } ;
5
6
@@ -10,6 +11,9 @@ extern_class! {
10
11
///
11
12
/// Can be used to identify types, interfaces, and other items.
12
13
///
14
+ /// Conversion methods to/from UUIDs from the `uuid` crate can be
15
+ /// enabled with the `uuid` crate feature.
16
+ ///
13
17
/// See [Apple's documentation](https://developer.apple.com/documentation/foundation/nsuuid?language=objc).
14
18
#[ derive( Debug , PartialEq , Eq , Hash ) ]
15
19
unsafe pub struct NSUUID : NSObject ;
@@ -35,12 +39,15 @@ impl UnwindSafe for NSUUID {}
35
39
impl RefUnwindSafe for NSUUID { }
36
40
37
41
impl NSUUID {
38
- // TODO: `nil` method?
39
-
40
42
pub fn new_v4 ( ) -> Id < Self , Shared > {
41
43
unsafe { msg_send_id ! [ Self :: class( ) , new] . unwrap ( ) }
42
44
}
43
45
46
+ /// The 'nil UUID'.
47
+ pub fn nil ( ) -> Id < Self , Shared > {
48
+ Self :: from_bytes ( [ 0 ; 16 ] )
49
+ }
50
+
44
51
pub fn from_bytes ( bytes : [ u8 ; 16 ] ) -> Id < Self , Shared > {
45
52
let bytes = UuidBytes ( bytes) ;
46
53
unsafe {
@@ -49,7 +56,12 @@ impl NSUUID {
49
56
}
50
57
}
51
58
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
+ }
53
65
54
66
pub fn as_bytes ( & self ) -> [ u8 ; 16 ] {
55
67
let mut bytes = UuidBytes ( [ 0 ; 16 ] ) ;
@@ -58,11 +70,40 @@ impl NSUUID {
58
70
}
59
71
}
60
72
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
+
61
89
/// Conversion methods to/from `uuid` crate.
62
90
#[ 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
+ }
66
107
67
108
unsafe impl NSCopying for NSUUID {
68
109
type Ownership = Shared ;
@@ -92,4 +133,20 @@ mod tests {
92
133
let uuid = NSUUID :: from_bytes ( [ 10 ; 16 ] ) ;
93
134
assert_eq ! ( uuid. as_bytes( ) , [ 10 ; 16 ] ) ;
94
135
}
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
+ }
95
152
}
0 commit comments