rust_macios/objective_c_runtime/traits.rs
1use objc::{
2 msg_send,
3 runtime::{Class, Protocol, Sel},
4 sel, sel_impl,
5};
6
7use crate::{
8 foundation::{NSString, UInt},
9 utils::to_bool,
10};
11
12use super::id;
13
14/// The group of methods that are fundamental to all Objective-C objects.
15pub trait INSObject {
16 /* Creating, Copying, and Deallocating Objects
17 */
18
19 /// Implemented by subclasses to initialize a new object (the receiver) immediately after memory for it has been allocated.
20 fn new() -> Self;
21
22 /// Returns a an `id`.
23 fn to_id(self) -> id;
24
25 /// Returns `Self` representation of the object.
26 ///
27 /// # Safety
28 ///
29 /// This function dereferences a raw pointer
30 unsafe fn from_id(obj: id) -> Self;
31
32 /* Describing Objects
33 */
34
35 /// Returns a string that represents the contents of the receiving class.
36 fn description(&self) -> NSString;
37
38 /* Supporting Discardable Content
39 */
40
41 /// Returns a string that represents the contents of the receiving class.
42 fn debug_description(&self) -> NSString;
43
44 /* Obselte Methods
45 */
46
47 /// Increments the receiver’s reference count.
48 fn retain(&self) -> Self;
49}
50
51/// The group of methods that are fundamental to all Objective-C objects.
52pub trait PNSObject {
53 /// Allocates a new instance of the receiving class, sends it an init message, and returns the initialized object.
54 fn m_new() -> Self
55 where
56 Self: Sized + FromId,
57 {
58 unsafe { Self::from_id(msg_send![Self::m_class(), new]) }
59 }
60
61 /// Returns a new instance of the receiving class.
62 fn m_alloc() -> Self
63 where
64 Self: Sized + FromId,
65 {
66 unsafe { Self::from_id(msg_send![Self::m_class(), alloc]) }
67 }
68
69 /// Initializes the class before it receives its first message.
70 fn m_initialize() {
71 unsafe { msg_send![Self::m_class(), initialize] }
72 }
73
74 /* Identifying Classes
75 */
76
77 /// Returns the class object for the receiver’s class.
78 fn m_class<'a>() -> &'a Class;
79
80 /// Returns the class object for the receiver’s superclass.
81 fn ip_superclass<'a>() -> Option<&'a Class> {
82 Self::m_class().superclass()
83 }
84
85 /* Identifying and Comparing Objects
86 */
87
88 /// Returns a Boolean value that indicates whether the receiver and a given object are equal.
89 fn m_is_equal(&self, object: &Self) -> bool {
90 unsafe { to_bool(msg_send![self.m_self(), isEqual: object]) }
91 }
92
93 /// Returns an integer that can be used as a table address in a hash table structure.
94 fn p_hash(&self) -> UInt {
95 unsafe { msg_send![self.m_self(), hash] }
96 }
97
98 /// Returns the receiver.
99 fn m_self(&self) -> id;
100
101 /* Testing Object Inheritance, Behavior, and Conformance
102 */
103
104 /// Returns a Boolean value that indicates whether the receiver is an instance of given class or an instance of any class that inherits from that class.
105 fn m_is_kind_of_class(&self, class: Class) -> bool {
106 unsafe { to_bool(msg_send![self.m_self(), isKindOfClass: class]) }
107 }
108
109 /// Returns a Boolean value that indicates whether the receiver is an instance of a given class.
110 fn m_is_member_of_class(&self, class: Class) -> bool {
111 unsafe { to_bool(msg_send![self.m_self(), isMemberOfClass: class]) }
112 }
113
114 /// Returns a Boolean value that indicates whether the receiver implements or inherits a method that can respond to a specified message.
115 fn m_responds_to_selector(&self, selector: Sel) -> bool {
116 unsafe { to_bool(msg_send![self.m_self(), respondsToSelector: selector]) }
117 }
118
119 /// Returns a Boolean value that indicates whether the receiver conforms to a given protocol.
120 fn m_conforms_to_protocol(&self, protocol: Protocol) -> bool {
121 unsafe { to_bool(msg_send![self.m_self(), conformsToProtocol: protocol]) }
122 }
123
124 /* Describing Objects
125 */
126
127 /// A textual representation of the receiver.
128 fn p_description(&self) -> NSString {
129 unsafe { NSString::from_id(msg_send![self.m_self(), description]) }
130 }
131
132 /// A textual representation of the receiver to use with a debugger.
133 fn p_debug_description(&self) -> NSString {
134 unsafe { NSString::from_id(msg_send![self.m_self(), debugDescription]) }
135 }
136
137 /* Sending Messages
138 */
139
140 /// Sends a specified message to the receiver and returns the result of the message.
141 fn m_perform_selector(&self, selector: Sel) -> id {
142 unsafe { msg_send![self.m_self(), performSelector: selector] }
143 }
144
145 /// Sends a message to the receiver with an object as the argument.
146 fn m_perform_selector_with_object(&self, selector: Sel, with_object: id) -> id {
147 unsafe { msg_send![self.m_self(), performSelector: selector withObject: with_object] }
148 }
149
150 /* Identifying Proxies
151 */
152
153 /// Returns a Boolean value that indicates whether the receiver does not descend from NSObject.
154 fn m_is_proxy(&self) -> bool {
155 unsafe { to_bool(msg_send![self.m_self(), isProxy]) }
156 }
157}
158
159/// Converting an Objective-C pointer to Object
160pub trait FromId: ToId {
161 /// Returns `Self` representation of the object.
162 ///
163 /// # Safety
164 ///
165 /// This function dereferences a raw pointer
166 unsafe fn from_id(ptr: id) -> Self;
167}
168
169/// Converting Object to an Objective-C pointer
170pub trait ToId {
171 /// Returns `id` representation of the object.
172 fn to_id(self) -> id;
173}