Skip to content

Commit aa3d16e

Browse files
committed
Add some simply tests for base types
1 parent 87fd8c6 commit aa3d16e

1 file changed

Lines changed: 34 additions & 3 deletions

File tree

crates/mac_core/src/lib.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub use url::CFUrl;
3030

3131
/// An ID representing different [`CFType`] subclasses (and of course, [`CFType`]. itself). Can
3232
/// be used for dynamic upcasting and downcasting of values.
33-
#[derive(Copy, Clone, PartialEq, Eq)]
33+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
3434
pub struct CFTypeId(libc::c_ulong);
3535

3636
impl CFTypeId {
@@ -56,7 +56,12 @@ pub struct CFType(NonNull<()>);
5656
impl CFType {
5757
/// Attempt to convert this type into a more specific child type. If the cast fails, `Err`
5858
/// contains the original [`CFType`].
59-
pub fn downcast<T: CoreType>(self) -> Result<T, Self> {
59+
///
60+
/// # Safety
61+
///
62+
/// This method cannot check the validity of casting from `CFArray<T> -> CFType -> CFArray<U>`
63+
/// in general. It is an obligation of the caller to ensure the container type is preserved.
64+
pub unsafe fn downcast<T: CoreType>(self) -> Result<T, Self> {
6065
if CFTypeId::of_val(&self) == CFTypeId::of::<T>() {
6166
let this = ManuallyDrop::new(self);
6267
// SAFETY: If the CFTypeId of self matches T, then it is guaranteed a valid pointer to T.
@@ -111,7 +116,8 @@ pub unsafe trait CoreType: Sized {
111116
/// The system type for this value. This is a pointer type in the `sys` module generally.
112117
type SysTy;
113118

114-
/// The [`CFTypeId`] that this type represents.
119+
/// The [`CFTypeId`] that this type represents. This is insufficient to ensure equality - for
120+
/// example, [`CFArray<A>`]` == `[`CFArray<B>`]
115121
fn type_id() -> CFTypeId;
116122

117123
/// # Safety
@@ -137,3 +143,28 @@ pub unsafe trait CoreType: Sized {
137143
/// Upcast this value into a [`CFType`] for usage in generic contexts.
138144
fn into_ty(self) -> CFType;
139145
}
146+
147+
#[cfg(test)]
148+
mod tests {
149+
use super::*;
150+
151+
#[test]
152+
fn test_type_id() {
153+
let arr = CFArray::<CFType>::empty();
154+
assert_eq!(CFTypeId::of::<CFArray<CFType>>(), CFTypeId::of_val(&arr));
155+
assert_eq!(
156+
CFTypeId::of::<CFArray<CFString>>(),
157+
CFTypeId::of::<CFArray<CFUrl>>()
158+
);
159+
assert_ne!(CFTypeId::of::<CFString>(), CFTypeId::of::<CFUrl>());
160+
}
161+
162+
#[test]
163+
fn test_upcast() {
164+
let arr = CFArray::<CFType>::empty();
165+
let ty = arr.into_ty();
166+
167+
assert_eq!(CFTypeId::of_val(&ty), CFTypeId::of::<CFArray<CFType>>());
168+
drop(ty);
169+
}
170+
}

0 commit comments

Comments
 (0)