objc2_core_foundation/type_traits.rs
1use core::ptr::NonNull;
2
3use crate::CFRetained;
4
5/// A CoreFoundation-like type.
6///
7/// This trait is implemented for all CoreFoundation-like types (i.e. both
8/// types in this crate like `CFString`, but also types from other frameworks
9/// like `CGColor` from CoreGraphics).
10///
11/// This trait allows the type to be used in [`CFRetained`].
12///
13/// You should not need to implement this yourself.
14///
15///
16/// # Safety
17///
18/// - The type must be a CoreFoundation-like type.
19/// - The type must be safe to retain/release using `CFRetain` and
20/// `CFRelease`.
21pub unsafe trait Type {
22 /// Increment the reference count of the receiver.
23 ///
24 /// This extends the duration in which the receiver is alive by detaching
25 /// it from the lifetime information carried by the reference.
26 ///
27 /// This is similar to using [`Clone` on `CFRetained<Self>`][clone-id],
28 /// with the addition that it can be used on a plain reference.
29 ///
30 /// [clone-id]: crate::CFRetained#impl-Clone-for-CFRetained<T>
31 #[inline]
32 #[doc(alias = "CFRetain")]
33 fn retain(&self) -> CFRetained<Self>
34 where
35 Self: Sized,
36 {
37 let ptr = NonNull::from(self);
38
39 // SAFETY: The pointer is valid, since it came from a Rust reference.
40 unsafe { CFRetained::retain(ptr) }
41 }
42}
43
44/// A concrete CoreFoundation type.
45///
46/// This trait is implemented for CoreFoundation types which have a
47/// `CFTypeID`, which should be most types except for mutable variants, as
48/// well as the root `CFType`.
49///
50///
51/// # Mutable types
52///
53/// Some types have immutable and mutable variants, the prime example being
54/// `CFString` and `CFMutableString`. Internally, these are very complex class
55/// clusters, but in the simplest case they're sometimes the same type, the
56/// only difference being that the mutable variant has a boolean flag set.
57/// This means that they also share the same type ID, and thus we cannot
58/// (stably) differentiate between them at runtime.
59///
60/// Therefore, this trait is only implemented for the immutable variant, to
61/// prevent it from accidentally being misused (it is unclear whether it would
62/// be unsound or not). If you're looking to convert to a mutable type, you'll
63/// have to either construct a new one with APIs like
64/// `CFStringCreateMutableCopy`, or use an unchecked cast.
65///
66///
67/// # Safety
68///
69/// - The type must not be mutable.
70/// - The [`type_id`][Self::type_id] must be implemented correctly, and must
71/// uniquely identify the type.
72pub unsafe trait ConcreteType: Type {
73 /// Get the unique `CFTypeID` identifier for the type.
74 ///
75 /// For example, this corresponds to `CFStringGetTypeID` for `CFString`
76 /// and `CGColorGetTypeID` for `CGColor`.
77 #[doc(alias = "GetTypeID")]
78 fn type_id() -> crate::__cf_macro_helpers::CFTypeID;
79}