1use std::mem;
2
3use core_foundation::{
4 base::{kCFAllocatorDefault, CFAllocatorRef, CFGetTypeID, CFRetain, CFType, CFTypeID, CFTypeRef, TCFType, TCFTypeRef},
5 dictionary::{CFDictionary, CFDictionaryRef},
6 string::{CFString, CFStringRef},
7};
8
9pub type CMAttachmentBearerRef = CFTypeRef;
10
11pub type CMAttachmentMode = u32;
12
13pub const kCMAttachmentMode_ShouldNotPropagate: CMAttachmentMode = 0;
14pub const kCMAttachmentMode_ShouldPropagate: CMAttachmentMode = 1;
15
16extern "C" {
17 pub fn CMSetAttachment(target: CMAttachmentBearerRef, key: CFStringRef, value: CFTypeRef, attachmentMode: CMAttachmentMode);
18 pub fn CMGetAttachment(target: CMAttachmentBearerRef, key: CFStringRef, attachmentModeOut: *mut CMAttachmentMode) -> CFTypeRef;
19 pub fn CMRemoveAttachment(target: CMAttachmentBearerRef, key: CFStringRef);
20 pub fn CMRemoveAllAttachments(target: CMAttachmentBearerRef);
21 pub fn CMCopyDictionaryOfAttachments(
22 allocator: CFAllocatorRef,
23 target: CMAttachmentBearerRef,
24 attachmentMode: CMAttachmentMode,
25 ) -> CFDictionaryRef;
26 pub fn CMSetAttachments(target: CMAttachmentBearerRef, theAttachments: CFDictionaryRef, attachmentMode: CMAttachmentMode);
27 pub fn CMPropagateAttachments(source: CMAttachmentBearerRef, destination: CMAttachmentBearerRef);
28}
29
30pub trait CMAttachmentBearerSubClass: TCFType {
31 #[inline]
32 fn as_CMAttachmentBearer(&self) -> CMAttachmentBearer {
33 unsafe { CMAttachmentBearer::wrap_under_get_rule(self.as_concrete_TypeRef().as_void_ptr()) }
34 }
35
36 #[inline]
37 fn into_CMAttachmentBearer(self) -> CMAttachmentBearer
38 where
39 Self: Sized,
40 {
41 let reference = self.as_concrete_TypeRef().as_void_ptr();
42 mem::forget(self);
43 unsafe { CMAttachmentBearer::wrap_under_create_rule(reference) }
44 }
45}
46
47declare_TCFType! {
48 CMAttachmentBearer, CMAttachmentBearerRef
49}
50impl_CFTypeDescription!(CMAttachmentBearer);
51
52impl CMAttachmentBearer {
53 #[inline]
54 pub fn as_concrete_TypeRef(&self) -> CMAttachmentBearerRef {
55 self.0
56 }
57
58 #[inline]
59 pub fn as_CFType(&self) -> CFType {
60 unsafe { CFType::wrap_under_get_rule(self.as_concrete_TypeRef()) }
61 }
62
63 #[inline]
64 pub fn as_CFTypeRef(&self) -> CFTypeRef {
65 self.as_concrete_TypeRef() as CFTypeRef
66 }
67
68 #[inline]
69 pub fn into_CFType(self) -> CFType
70 where
71 Self: Sized,
72 {
73 let reference = self.as_CFTypeRef();
74 mem::forget(self);
75 unsafe { CFType::wrap_under_create_rule(reference) }
76 }
77
78 #[inline]
79 pub unsafe fn wrap_under_create_rule(reference: CMAttachmentBearerRef) -> Self {
80 CMAttachmentBearer(reference)
81 }
82
83 #[inline]
84 pub unsafe fn wrap_under_get_rule(reference: CMAttachmentBearerRef) -> Self {
85 let reference = CFRetain(reference);
86 CMAttachmentBearer(reference)
87 }
88
89 #[inline]
90 pub fn type_of(&self) -> CFTypeID {
91 unsafe { CFGetTypeID(self.as_CFTypeRef()) }
92 }
93
94 #[inline]
95 pub fn instance_of<T: TCFType>(&self) -> bool {
96 self.type_of() == T::type_id()
97 }
98}
99
100impl Clone for CMAttachmentBearer {
101 #[inline]
102 fn clone(&self) -> Self {
103 unsafe { CMAttachmentBearer::wrap_under_get_rule(self.as_concrete_TypeRef()) }
104 }
105}
106
107impl PartialEq for CMAttachmentBearer {
108 #[inline]
109 fn eq(&self, other: &Self) -> bool {
110 self.as_CFType().eq(&other.as_CFType())
111 }
112}
113
114impl Eq for CMAttachmentBearer {}
115
116impl CMAttachmentBearer {
117 #[inline]
118 pub fn downcast<T: CMAttachmentBearerSubClass>(&self) -> Option<T> {
119 if self.instance_of::<T>() {
120 Some(unsafe { T::wrap_under_get_rule(T::Ref::from_void_ptr(self.as_concrete_TypeRef())) })
121 } else {
122 None
123 }
124 }
125
126 #[inline]
127 pub fn downcast_into<T: CMAttachmentBearerSubClass>(self) -> Option<T> {
128 if self.instance_of::<T>() {
129 unsafe {
130 let reference = T::Ref::from_void_ptr(self.as_concrete_TypeRef());
131 mem::forget(self);
132 Some(T::wrap_under_create_rule(reference))
133 }
134 } else {
135 None
136 }
137 }
138}
139
140impl CMAttachmentBearer {
141 #[inline]
142 pub fn set_attachment(&self, key: &CFString, value: &CFType, attachment_mode: CMAttachmentMode) {
143 unsafe { CMSetAttachment(self.as_concrete_TypeRef(), key.as_concrete_TypeRef(), value.as_CFTypeRef(), attachment_mode) }
144 }
145
146 #[inline]
147 pub fn get_attachment(&self, key: &CFString) -> Option<(CFType, CMAttachmentMode)> {
148 unsafe {
149 let mut attachment_mode = 0;
150 let value = CMGetAttachment(self.as_concrete_TypeRef(), key.as_concrete_TypeRef(), &mut attachment_mode);
151 if value.is_null() {
152 None
153 } else {
154 Some((TCFType::wrap_under_create_rule(value), attachment_mode))
155 }
156 }
157 }
158
159 #[inline]
160 pub fn remove_attachment(&self, key: &CFString) {
161 unsafe { CMRemoveAttachment(self.as_concrete_TypeRef(), key.as_concrete_TypeRef()) }
162 }
163
164 #[inline]
165 pub fn remove_all_attachments(&self) {
166 unsafe { CMRemoveAllAttachments(self.as_concrete_TypeRef()) }
167 }
168
169 #[inline]
170 pub fn copy_dictionary_of_attachments(&self, attachment_mode: CMAttachmentMode) -> Option<CFDictionary<CFString, CFType>> {
171 unsafe {
172 let dict = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, self.as_concrete_TypeRef(), attachment_mode);
173 if dict.is_null() {
174 None
175 } else {
176 Some(TCFType::wrap_under_create_rule(dict))
177 }
178 }
179 }
180
181 #[inline]
182 pub fn set_attachments(&self, the_attachments: &CFDictionary<CFString, CFType>, attachment_mode: CMAttachmentMode) {
183 unsafe { CMSetAttachments(self.as_concrete_TypeRef(), the_attachments.as_concrete_TypeRef(), attachment_mode) }
184 }
185
186 #[inline]
187 pub fn propagate_attachments(&self, destination: &mut CMAttachmentBearer) {
188 unsafe { CMPropagateAttachments(self.as_concrete_TypeRef(), destination.0) }
189 }
190}