objc_foundation/
object.rs1use std::any::Any;
2
3use objc::Message;
4use objc::runtime::{BOOL, Class, NO};
5use objc_id::{Id, ShareId};
6
7use NSString;
8
9pub trait INSObject : Any + Sized + Message {
16 fn class() -> &'static Class;
17
18 fn hash_code(&self) -> usize {
19 unsafe {
20 msg_send![self, hash]
21 }
22 }
23
24 fn is_equal<T>(&self, other: &T) -> bool where T: INSObject {
25 let result: BOOL = unsafe {
26 msg_send![self, isEqual:other]
27 };
28 result != NO
29 }
30
31 fn description(&self) -> ShareId<NSString> {
32 unsafe {
33 let result: *mut NSString = msg_send![self, description];
34 Id::from_ptr(result)
35 }
36 }
37
38 fn is_kind_of(&self, cls: &Class) -> bool {
39 let result: BOOL = unsafe {
40 msg_send![self, isKindOfClass:cls]
41 };
42 result != NO
43 }
44
45 fn new() -> Id<Self> {
46 let cls = Self::class();
47 unsafe {
48 let obj: *mut Self = msg_send![cls, alloc];
49 let obj: *mut Self = msg_send![obj, init];
50 Id::from_retained_ptr(obj)
51 }
52 }
53}
54
55object_struct!(NSObject);
56
57#[cfg(test)]
58mod tests {
59 use {INSString, NSString};
60 use super::{INSObject, NSObject};
61
62 #[test]
63 fn test_is_equal() {
64 let obj1 = NSObject::new();
65 assert!(obj1.is_equal(&*obj1));
66
67 let obj2 = NSObject::new();
68 assert!(!obj1.is_equal(&*obj2));
69 }
70
71 #[test]
72 fn test_hash_code() {
73 let obj = NSObject::new();
74 assert!(obj.hash_code() == obj.hash_code());
75 }
76
77 #[test]
78 fn test_description() {
79 let obj = NSObject::new();
80 let description = obj.description();
81 let expected = format!("<NSObject: {:p}>", &*obj);
82 assert!(description.as_str() == &*expected);
83 }
84
85 #[test]
86 fn test_is_kind_of() {
87 let obj = NSObject::new();
88 assert!(obj.is_kind_of(NSObject::class()));
89 assert!(!obj.is_kind_of(NSString::class()));
90 }
91}