1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use core::fmt;
use core::hash;
use objc2::rc::{DefaultId, Id, Owned, Shared};
use objc2::runtime::{Class, Object};
use objc2::{class, msg_send, msg_send_bool, msg_send_id};
use super::NSString;
__inner_extern_class! {
@__inner
unsafe pub struct NSObject<>: Object {}
}
impl NSObject {
#[inline]
pub fn class() -> &'static Class {
class!(NSObject)
}
}
impl NSObject {
unsafe_def_fn!(pub fn new -> Owned);
pub fn hash_code(&self) -> usize {
unsafe { msg_send![self, hash] }
}
pub fn is_equal(&self, other: &NSObject) -> bool {
unsafe { msg_send_bool![self, isEqual: other] }
}
pub fn description(&self) -> Id<NSString, Shared> {
unsafe { msg_send_id![self, description].unwrap() }
}
pub fn is_kind_of(&self, cls: &Class) -> bool {
unsafe { msg_send_bool![self, isKindOfClass: cls] }
}
}
impl PartialEq for NSObject {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.is_equal(other)
}
}
impl Eq for NSObject {}
impl hash::Hash for NSObject {
#[inline]
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.hash_code().hash(state);
}
}
impl fmt::Debug for NSObject {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.description(), f)
}
}
impl DefaultId for NSObject {
type Ownership = Owned;
#[inline]
fn default_id() -> Id<Self, Self::Ownership> {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::format;
#[test]
fn test_deref() {
let mut obj: Id<NSObject, Owned> = NSObject::new();
let _: &NSObject = &obj;
let _: &mut NSObject = &mut obj;
let _: &Object = &obj;
let _: &mut Object = &mut obj;
}
#[test]
fn test_as_ref_borrow() {
use core::borrow::{Borrow, BorrowMut};
fn impls_as_ref<T: AsRef<U> + Borrow<U> + ?Sized, U: ?Sized>(_: &T) {}
fn impls_as_mut<T: AsMut<U> + BorrowMut<U> + ?Sized, U: ?Sized>(_: &mut T) {}
let mut obj = NSObject::new();
impls_as_ref::<Id<NSObject, Owned>, NSObject>(&obj);
impls_as_mut::<Id<NSObject, Owned>, NSObject>(&mut obj);
impls_as_ref::<NSObject, NSObject>(&obj);
impls_as_mut::<NSObject, NSObject>(&mut obj);
impls_as_ref::<NSObject, Object>(&obj);
impls_as_mut::<NSObject, Object>(&mut obj);
}
#[test]
fn test_equality() {
let obj1 = NSObject::new();
assert_eq!(obj1, obj1);
let obj2 = NSObject::new();
assert_ne!(obj1, obj2);
}
#[test]
fn test_hash_code() {
let obj = NSObject::new();
assert_eq!(obj.hash_code(), obj.hash_code());
}
#[test]
fn test_debug() {
let obj = NSObject::new();
let expected = format!("<NSObject: {:p}>", &*obj);
assert_eq!(format!("{:?}", obj), format!("{:?}", expected));
}
#[test]
fn test_is_kind_of() {
let obj = NSObject::new();
assert!(obj.is_kind_of(NSObject::class()));
assert!(!obj.is_kind_of(NSString::class()));
}
}