rust_macios/contacts/
cn_contact.rs1use std::fmt::Debug;
2
3use crate::{
4 foundation::{NSArray, NSComparator, NSData, NSDateComponents, NSPredicate, NSString},
5 object,
6 objective_c_runtime::{
7 id,
8 macros::interface_impl,
9 nil,
10 traits::{FromId, PNSObject},
11 },
12 utils::to_bool,
13};
14use objc::{msg_send, sel, sel_impl};
15
16use super::{
17 CNContactRelation, CNInstantMessageAddress, CNLabeledValue, CNPhoneNumber, CNPostalAddress,
18 CNSocialProfile,
19};
20
21#[derive(Debug, Copy, Clone, PartialEq, Eq)]
23#[repr(i64)]
24pub enum CNContactType {
25 Person,
27 Organization,
29}
30
31#[derive(Debug, Copy, Clone, PartialEq, Eq)]
33#[repr(i64)]
34pub enum CNContactSortOrder {
35 None,
37 UserDefault,
39 GivenName,
41 FamilyName,
43}
44
45object! {
46 unsafe pub struct CNContact;
48}
49
50#[interface_impl(NSObject)]
51impl CNContact {
52 #[property]
57 pub fn identifier(&self) -> NSString {
58 unsafe { NSString::from_id(msg_send![self.m_self(), identifier]) }
59 }
60
61 #[property]
63 pub fn contact_type(&self) -> CNContactType {
64 unsafe { msg_send![self.m_self(), contactType] }
65 }
66
67 #[property]
69 pub fn name_prefix(&self) -> NSString {
70 unsafe { NSString::from_id(msg_send![self.m_self(), namePrefix]) }
71 }
72
73 #[property]
75 pub fn given_name(&self) -> NSString {
76 unsafe { NSString::from_id(msg_send![self.m_self(), givenName]) }
77 }
78
79 #[property]
81 pub fn middle_name(&self) -> NSString {
82 unsafe { NSString::from_id(msg_send![self.m_self(), middleName]) }
83 }
84
85 #[property]
87 pub fn family_name(&self) -> NSString {
88 unsafe { NSString::from_id(msg_send![self.m_self(), familyName]) }
89 }
90
91 #[property]
93 pub fn previous_family_name(&self) -> NSString {
94 unsafe { NSString::from_id(msg_send![self.m_self(), previousFamilyName]) }
95 }
96
97 #[property]
99 pub fn name_suffix(&self) -> NSString {
100 unsafe { NSString::from_id(msg_send![self.m_self(), nameSuffix]) }
101 }
102
103 #[property]
105 pub fn nickname(&self) -> NSString {
106 unsafe { NSString::from_id(msg_send![self.m_self(), nickname]) }
107 }
108
109 #[property]
111 pub fn phonetic_given_name(&self) -> NSString {
112 unsafe { NSString::from_id(msg_send![self.m_self(), phoneticGivenName]) }
113 }
114
115 #[property]
117 pub fn phonetic_middle_name(&self) -> NSString {
118 unsafe { NSString::from_id(msg_send![self.m_self(), phoneticMiddleName]) }
119 }
120
121 #[property]
123 pub fn phonetic_family_name(&self) -> NSString {
124 unsafe { NSString::from_id(msg_send![self.m_self(), phoneticFamilyName]) }
125 }
126
127 #[property]
132 pub fn job_title(&self) -> NSString {
133 unsafe { NSString::from_id(msg_send![self.m_self(), jobTitle]) }
134 }
135
136 #[property]
138 pub fn department_name(&self) -> NSString {
139 unsafe { NSString::from_id(msg_send![self.m_self(), departmentName]) }
140 }
141
142 #[property]
144 pub fn organization_name(&self) -> NSString {
145 unsafe { NSString::from_id(msg_send![self.m_self(), organizationName]) }
146 }
147
148 #[property]
150 pub fn phonetic_organization_name(&self) -> NSString {
151 unsafe { NSString::from_id(msg_send![self.m_self(), phoneticOrganizationName]) }
152 }
153
154 #[property]
159 pub fn postal_addresses(&self) -> NSArray<CNLabeledValue<CNPostalAddress>> {
160 unsafe { NSArray::from_id(msg_send![self.m_self(), postalAddresses]) }
161 }
162
163 #[property]
165 pub fn email_addresses(&self) -> NSArray<CNLabeledValue<NSString>> {
166 unsafe { NSArray::from_id(msg_send![self.m_self(), emailAddresses]) }
167 }
168
169 #[property]
171 pub fn url_addresses(&self) -> NSArray<CNLabeledValue<NSString>> {
172 unsafe { NSArray::from_id(msg_send![self.m_self(), urlAddresses]) }
173 }
174
175 #[property]
180 pub fn phone_numbers(&self) -> NSArray<CNLabeledValue<CNPhoneNumber>> {
181 unsafe { NSArray::from_id(msg_send![self.m_self(), phoneNumbers]) }
182 }
183
184 #[property]
189 pub fn social_profiles(&self) -> NSArray<CNLabeledValue<CNSocialProfile>> {
190 unsafe { NSArray::from_id(msg_send![self.m_self(), socialProfiles]) }
191 }
192
193 #[property]
195 pub fn birthday(&self) -> Option<NSDateComponents> {
196 unsafe {
197 let ptr = msg_send![self.m_self(), birthday];
198
199 if ptr != nil {
200 Some(NSDateComponents::from_id(ptr))
201 } else {
202 None
203 }
204 }
205 }
206
207 #[property]
212 pub fn non_gregorian_birthday(&self) -> Option<NSDateComponents> {
213 unsafe {
214 let ptr = msg_send![self.m_self(), nonGregorianBirthday];
215
216 if ptr != nil {
217 Some(NSDateComponents::from_id(ptr))
218 } else {
219 None
220 }
221 }
222 }
223
224 #[property]
226 pub fn dates(&self) -> NSArray<CNLabeledValue<NSDateComponents>> {
227 unsafe { NSArray::from_id(msg_send![self.m_self(), dates]) }
228 }
229
230 #[property]
232 pub fn note(&self) -> NSString {
233 unsafe { NSString::from_id(msg_send![self.m_self(), note]) }
234 }
235
236 #[property]
241 pub fn image_data(&self) -> Option<NSData> {
242 unsafe {
243 let ptr = msg_send![self.m_self(), imageData];
244
245 if ptr != nil {
246 Some(NSData::from_id(ptr))
247 } else {
248 None
249 }
250 }
251 }
252
253 #[property]
255 pub fn thumbnail_image_data(&self) -> Option<NSData> {
256 unsafe {
257 let ptr = msg_send![self.m_self(), thumbnailImageData];
258
259 if ptr != nil {
260 Some(NSData::from_id(ptr))
261 } else {
262 None
263 }
264 }
265 }
266
267 #[property]
269 pub fn image_data_available(&self) -> bool {
270 unsafe { to_bool(msg_send![self.m_self(), imageDataAvailable]) }
271 }
272
273 #[property]
278 pub fn contact_relations(&self) -> NSArray<CNLabeledValue<CNContactRelation>> {
279 unsafe { NSArray::from_id(msg_send![self.m_self(), contactRelations]) }
280 }
281
282 #[property]
284 pub fn instant_messaging_addresses(&self) -> NSArray<CNLabeledValue<CNInstantMessageAddress>> {
285 unsafe { NSArray::from_id(msg_send![self.m_self(), instantMessageAddresses]) }
286 }
287
288 #[method]
293 pub fn localized_string_for_key(property: NSString) -> NSString {
294 unsafe { NSString::from_id(msg_send![Self::m_class(), localizedStringForKey: property]) }
295 }
296
297 #[method]
302 pub fn descriptor_for_all_comparator_keys() -> id {
303 unsafe { msg_send![Self::m_class(), descriptorForAllComparatorKeys] }
304 }
305
306 #[method]
308 pub fn comparator_for_name_sort_order(sort_order: CNContactSortOrder) -> NSComparator {
309 unsafe { msg_send![Self::m_class(), comparatorForNameSortOrder: sort_order] }
310 }
311
312 #[method]
314 pub fn is_unified_with_contact_with_identifier(&self, identifier: NSString) -> bool {
315 unsafe {
316 to_bool(msg_send![
317 self.m_self(),
318 isUnifiedWithContactWithIdentifier: identifier
319 ])
320 }
321 }
322
323 #[method]
325 pub fn is_key_available(&self, key: NSString) -> bool {
326 unsafe { to_bool(msg_send![self.m_self(), isKeyAvailable: key]) }
327 }
328
329 #[method]
331 pub fn are_keys_available(&self, key_descriptors: NSArray<id>) -> bool {
332 unsafe { to_bool(msg_send![self.m_self(), areKeysAvailable: key_descriptors]) }
333 }
334
335 #[method]
340 pub fn predicate_for_contacts_matching_name(name: NSString) -> NSPredicate {
341 unsafe {
342 NSPredicate::from_id(msg_send![
343 Self::m_class(),
344 predicateForContactsMatchingName: name
345 ])
346 }
347 }
348
349 #[method]
351 pub fn predicate_for_contacts_with_identifiers(identifiers: NSArray<String>) -> NSPredicate {
352 unsafe {
353 NSPredicate::from_id(msg_send![
354 Self::m_class(),
355 predicateForContactsWithIdentifiers: identifiers
356 ])
357 }
358 }
359
360 #[method]
362 pub fn predicate_for_contacts_in_group_with_identifier(group: NSString) -> NSPredicate {
363 unsafe {
364 NSPredicate::from_id(msg_send![
365 Self::m_class(),
366 predicateForContactsInGroupWithIdentifier: group
367 ])
368 }
369 }
370
371 #[method]
373 pub fn predicate_for_contacts_in_container_with_identifier(container: NSString) -> NSPredicate {
374 unsafe {
375 NSPredicate::from_id(msg_send![
376 Self::m_class(),
377 predicateForContactsInContainerWithIdentifier: container
378 ])
379 }
380 }
381
382 #[method]
384 pub fn predicate_for_contacts_matching_phone_number(
385 phone_number: CNPhoneNumber,
386 ) -> NSPredicate {
387 unsafe {
388 NSPredicate::from_id(msg_send![
389 Self::m_class(),
390 predicateForContactsMatchingPhoneNumber: phone_number
391 ])
392 }
393 }
394
395 #[method]
397 pub fn predicate_for_contacts_matching_email_address(email_address: NSString) -> NSPredicate {
398 unsafe {
399 NSPredicate::from_id(msg_send![
400 Self::m_class(),
401 predicateForContactsMatchingEmailAddress: email_address
402 ])
403 }
404 }
405}
406
407#[cfg(test)]
408mod tests {
409 use crate::{contacts::CNContactType, objective_c_runtime::traits::PNSObject};
410
411 use super::CNContact;
412
413 #[test]
414 fn test_contact() {
415 let contact = CNContact::m_new();
416
417 assert!(contact.birthday().is_none());
418 assert!(contact.contact_relations().count() == 0);
419 assert!(contact.contact_type() == CNContactType::Person);
420 assert!(contact.dates().count() == 0);
421 assert!(contact.department_name() == "");
422 assert!(contact.email_addresses().count() == 0);
423 assert!(contact.family_name() == "");
424 assert!(contact.given_name() == "");
425 assert!(contact.identifier() != "");
426 assert!(contact.image_data().is_none());
427 assert!(!contact.image_data_available());
428 assert!(contact.instant_messaging_addresses().count() == 0);
429 assert!(contact.job_title() == "");
430 assert!(contact.middle_name() == "");
431 assert!(contact.name_prefix() == "");
432 assert!(contact.name_suffix() == "");
433 assert!(contact.nickname() == "");
434 assert!(contact.non_gregorian_birthday().is_none());
435 assert!(contact.note() == "");
436 assert!(contact.organization_name() == "");
437 assert!(contact.phone_numbers().count() == 0);
438 assert!(contact.phonetic_given_name() == "");
439 assert!(contact.phonetic_middle_name() == "");
440 assert!(contact.phonetic_family_name() == "");
441 assert!(contact.postal_addresses().count() == 0);
442 assert!(contact.previous_family_name() == "");
443 assert!(contact.social_profiles().count() == 0);
444 assert!(contact.thumbnail_image_data().is_none());
445 assert!(contact.url_addresses().count() == 0);
446 }
447}