diff --git a/core-foundation-sys/Cargo.toml b/core-foundation-sys/Cargo.toml index 3d997e5..02d4b88 100644 --- a/core-foundation-sys/Cargo.toml +++ b/core-foundation-sys/Cargo.toml @@ -3,7 +3,7 @@ name = "core-foundation-sys" description = "Bindings to Core Foundation for OS X" homepage = "https://github.com/servo/core-foundation-rs" repository = "https://github.com/servo/core-foundation-rs" -version = "0.4.6" +version = "0.5.0" authors = ["The Servo Project Developers"] license = "MIT / Apache-2.0" build = "build.rs" diff --git a/core-foundation-sys/src/base.rs b/core-foundation-sys/src/base.rs index 2d63d8b..bb36b30 100644 --- a/core-foundation-sys/src/base.rs +++ b/core-foundation-sys/src/base.rs @@ -80,6 +80,23 @@ pub struct CFAllocatorContext { pub preferredSize: CFAllocatorPreferredSizeCallBack } +/// Trait for all types which are Core Foundation reference types. +pub trait TCFTypeRef { + fn as_void_ptr(&self) -> *const c_void; + + unsafe fn from_void_ptr(ptr: *const c_void) -> Self; +} + +impl TCFTypeRef for *const T { + fn as_void_ptr(&self) -> *const c_void { + (*self) as *const c_void + } + + unsafe fn from_void_ptr(ptr: *const c_void) -> Self { + ptr as *const T + } +} + extern { /* * CFBase.h diff --git a/core-foundation-sys/src/error.rs b/core-foundation-sys/src/error.rs index 68097da..2358478 100644 --- a/core-foundation-sys/src/error.rs +++ b/core-foundation-sys/src/error.rs @@ -15,7 +15,7 @@ use string::CFStringRef; #[repr(C)] pub struct __CFError(c_void); -pub type CFErrorRef = *mut __CFError; +pub type CFErrorRef = *const __CFError; extern "C" { pub fn CFErrorGetTypeID() -> CFTypeID; diff --git a/core-foundation/Cargo.toml b/core-foundation/Cargo.toml index 3d90ca9..26ab4de 100644 --- a/core-foundation/Cargo.toml +++ b/core-foundation/Cargo.toml @@ -3,13 +3,13 @@ name = "core-foundation" description = "Bindings to Core Foundation for OS X" homepage = "https://github.com/servo/core-foundation-rs" repository = "https://github.com/servo/core-foundation-rs" -version = "0.4.6" +version = "0.5.0" authors = ["The Servo Project Developers"] license = "MIT / Apache-2.0" [dependencies.core-foundation-sys] path = "../core-foundation-sys" -version = "0.4.6" +version = "0.5.0" [dependencies] libc = "0.2" diff --git a/core-foundation/src/array.rs b/core-foundation/src/array.rs index ced572c..4dde62c 100644 --- a/core-foundation/src/array.rs +++ b/core-foundation/src/array.rs @@ -12,36 +12,51 @@ pub use core_foundation_sys::array::*; pub use core_foundation_sys::base::{CFIndex, CFRelease}; use core_foundation_sys::base::{CFTypeRef, kCFAllocatorDefault}; -use base::CFType; use libc::c_void; use std::mem; use std::marker::PhantomData; +use std; +use std::ops::Deref; +use std::fmt::{Debug, Formatter}; -use base::{CFIndexConvertible, TCFType, CFRange}; +use base::{CFIndexConvertible, TCFType, TCFTypeRef, CFRange}; /// A heterogeneous immutable array. pub struct CFArray(CFArrayRef, PhantomData); -/// A trait describing how to convert from the stored *const c_void to the desired T -pub unsafe trait FromVoid { - unsafe fn from_void(x: *const c_void) -> Self; +/// A reference to an element inside the array +pub struct ItemRef<'a, T: 'a>(T, PhantomData<&'a T>); + +impl<'a, T> Deref for ItemRef<'a, T> { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } } -unsafe impl FromVoid for u32 { - unsafe fn from_void(x: *const c_void) -> u32 { - x as usize as u32 +impl<'a, T: Debug> Debug for ItemRef<'a, T> { + fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { + self.0.fmt(f) } } -unsafe impl FromVoid for *const c_void { - unsafe fn from_void(x: *const c_void) -> *const c_void { - x +/// A trait describing how to convert from the stored *const c_void to the desired T +pub unsafe trait FromVoid { + unsafe fn from_void<'a>(x: *const c_void) -> ItemRef<'a, Self> where Self: std::marker::Sized; +} + +unsafe impl FromVoid for u32 { + unsafe fn from_void<'a>(x: *const c_void) -> ItemRef<'a, Self> { + // Functions like CGFontCopyTableTags treat the void*'s as u32's + // so we convert by casting directly + ItemRef(x as u32, PhantomData) } } -unsafe impl FromVoid for CFType { - unsafe fn from_void(x: *const c_void) -> CFType { - TCFType::wrap_under_get_rule(mem::transmute(x)) +unsafe impl FromVoid for T { + unsafe fn from_void<'a>(x: *const c_void) -> ItemRef<'a, Self> { + ItemRef(TCFType::wrap_under_create_rule(T::Ref::from_void_ptr(x)), PhantomData) } } @@ -57,9 +72,9 @@ pub struct CFArrayIterator<'a, T: 'a> { } impl<'a, T: FromVoid> Iterator for CFArrayIterator<'a, T> { - type Item = T; + type Item = ItemRef<'a, T>; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option> { if self.index >= self.array.len() { None } else { @@ -81,7 +96,7 @@ impl_CFTypeDescriptionGeneric!(CFArray); impl CFArray { /// Creates a new `CFArray` with the given elements, which must be `CFType` objects. - pub fn from_CFTypes(elems: &[T]) -> CFArray where T: TCFType { + pub fn from_CFTypes(elems: &[T]) -> CFArray where T: TCFType { unsafe { let elems: Vec = elems.iter().map(|elem| elem.as_CFTypeRef()).collect(); let array_ref = CFArrayCreate(kCFAllocatorDefault, @@ -92,11 +107,6 @@ impl CFArray { } } - #[deprecated(note = "please use `as_untyped` instead")] - pub fn to_untyped(self) -> CFArray { - unsafe { CFArray::wrap_under_get_rule(self.0) } - } - pub fn as_untyped(&self) -> CFArray { unsafe { CFArray::wrap_under_get_rule(self.0) } } @@ -122,7 +132,7 @@ impl CFArray { } #[inline] - pub fn get(&self, index: CFIndex) -> T where T: FromVoid { + pub fn get<'a>(&'a self, index: CFIndex) -> ItemRef<'a, T> where T: FromVoid { assert!(index < self.len()); unsafe { T::from_void(CFArrayGetValueAtIndex(self.0, index)) } } @@ -145,7 +155,7 @@ impl CFArray { } impl<'a, T: FromVoid> IntoIterator for &'a CFArray { - type Item = T; + type Item = ItemRef<'a, T>; type IntoIter = CFArrayIterator<'a, T>; fn into_iter(self) -> CFArrayIterator<'a, T> { @@ -157,15 +167,7 @@ impl<'a, T: FromVoid> IntoIterator for &'a CFArray { mod tests { use super::*; use std::mem; - - #[test] - fn to_untyped_correct_retain_count() { - let array = CFArray::::from_CFTypes(&[]); - assert_eq!(array.retain_count(), 1); - - let untyped_array = array.to_untyped(); - assert_eq!(untyped_array.retain_count(), 1); - } + use base::CFType; #[test] fn as_untyped_correct_retain_count() { @@ -180,6 +182,21 @@ mod tests { assert_eq!(untyped_array.retain_count(), 1); } + #[test] + fn borrow() { + use number::CFNumber; + + let n0 = CFNumber::from(0); + let n1 = CFNumber::from(1); + + let arr: CFArray = CFArray::from_CFTypes(&[ + n0, + n1 + ]); + let p = arr.get(0); + assert_eq!(p.to_i64().unwrap(), 0) + } + #[test] fn should_box_and_unbox() { use number::CFNumber; @@ -215,14 +232,14 @@ mod tests { assert_eq!(iter.len(), 5); for elem in iter { - let number: CFNumber = elem.downcast::<_, CFNumber>().unwrap(); + let number: CFNumber = elem.downcast::().unwrap(); sum += number.to_i64().unwrap() } assert!(sum == 15); for elem in arr.iter() { - let number: CFNumber = elem.downcast::<_, CFNumber>().unwrap(); + let number: CFNumber = elem.downcast::().unwrap(); sum += number.to_i64().unwrap() } diff --git a/core-foundation/src/base.rs b/core-foundation/src/base.rs index 768ba2e..981e61a 100644 --- a/core-foundation/src/base.rs +++ b/core-foundation/src/base.rs @@ -53,18 +53,19 @@ impl CFType { /// // Cast it up to a CFType. /// let cf_type: CFType = string.as_CFType(); /// // Cast it down again. - /// assert!(cf_type.downcast::<_, CFString>().unwrap().to_string() == "FooBar"); + /// assert!(cf_type.downcast::().unwrap().to_string() == "FooBar"); /// // Casting it to some other type will yield `None` - /// assert!(cf_type.downcast::<_, CFBoolean>().is_none()); + /// assert!(cf_type.downcast::().is_none()); /// ``` /// /// [`Box::downcast`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast /// [`CFPropertyList::downcast`]: ../propertylist/struct.CFPropertyList.html#method.downcast #[inline] - pub fn downcast>(&self) -> Option { - if self.instance_of::<_, T>() { + pub fn downcast(&self) -> Option { + if self.instance_of::() { unsafe { - Some(T::wrap_under_get_rule(self.0 as *const Raw)) + let reference = T::Ref::from_void_ptr(self.0); + Some(T::wrap_under_get_rule(reference)) } } else { None @@ -75,11 +76,13 @@ impl CFType { /// /// [`downcast`]: #method.downcast #[inline] - pub fn downcast_into>(self) -> Option { - if self.instance_of::<_, T>() { - let reference = self.0 as *const Raw; - mem::forget(self); - unsafe { Some(T::wrap_under_create_rule(reference)) } + pub fn downcast_into(self) -> Option { + if self.instance_of::() { + unsafe { + let reference = T::Ref::from_void_ptr(self.0); + mem::forget(self); + Some(T::wrap_under_create_rule(reference)) + } } else { None } @@ -126,16 +129,20 @@ impl CFAllocator { } } -/// All Core Foundation types implement this trait. The type parameter `TypeRef` specifies the + +/// All Core Foundation types implement this trait. The associated type `Ref` specifies the /// associated Core Foundation type: e.g. for `CFType` this is `CFTypeRef`; for `CFArray` this is /// `CFArrayRef`. -pub trait TCFType { +pub trait TCFType { + /// The reference type wrapped inside this type. + type Ref: TCFTypeRef; + /// Returns the object as its concrete TypeRef. - fn as_concrete_TypeRef(&self) -> ConcreteTypeRef; + fn as_concrete_TypeRef(&self) -> Self::Ref; /// Returns an instance of the object, wrapping the underlying `CFTypeRef` subclass. Use this /// when following Core Foundation's "Create Rule". The reference count is *not* bumped. - unsafe fn wrap_under_create_rule(obj: ConcreteTypeRef) -> Self; + unsafe fn wrap_under_create_rule(obj: Self::Ref) -> Self; /// Returns the type ID for this class. fn type_id() -> CFTypeID; @@ -152,7 +159,8 @@ pub trait TCFType { /// count. #[inline] fn into_CFType(self) -> CFType - where Self: Sized + where + Self: Sized, { let reference = self.as_CFTypeRef(); mem::forget(self); @@ -164,7 +172,7 @@ pub trait TCFType { /// Returns an instance of the object, wrapping the underlying `CFTypeRef` subclass. Use this /// when following Core Foundation's "Get Rule". The reference count *is* bumped. - unsafe fn wrap_under_get_rule(reference: ConcreteTypeRef) -> Self; + unsafe fn wrap_under_get_rule(reference: Self::Ref) -> Self; /// Returns the reference count of the object. It is unwise to do anything other than test /// whether the return value of this method is greater than zero. @@ -192,12 +200,14 @@ pub trait TCFType { /// Returns true if this value is an instance of another type. #[inline] - fn instance_of>(&self) -> bool { - self.type_of() == >::type_id() + fn instance_of(&self) -> bool { + self.type_of() == OtherCFType::type_id() } } -impl TCFType for CFType { +impl TCFType for CFType { + type Ref = CFTypeRef; + #[inline] fn as_concrete_TypeRef(&self) -> CFTypeRef { self.0 @@ -238,8 +248,8 @@ mod tests { let string = CFString::from_static_string("foo"); let cftype = string.as_CFType(); - assert!(cftype.instance_of::<_, CFString>()); - assert!(!cftype.instance_of::<_, CFBoolean>()); + assert!(cftype.instance_of::()); + assert!(!cftype.instance_of::()); } #[test] @@ -264,7 +274,7 @@ mod tests { fn as_cftype_and_downcast() { let string = CFString::from_static_string("bar"); let cftype = string.as_CFType(); - let string2 = cftype.downcast::<_, CFString>().unwrap(); + let string2 = cftype.downcast::().unwrap(); assert_eq!(string2.to_string(), "bar"); assert_eq!(string.retain_count(), 3); @@ -276,7 +286,7 @@ mod tests { fn into_cftype_and_downcast_into() { let string = CFString::from_static_string("bar"); let cftype = string.into_CFType(); - let string2 = cftype.downcast_into::<_, CFString>().unwrap(); + let string2 = cftype.downcast_into::().unwrap(); assert_eq!(string2.to_string(), "bar"); assert_eq!(string2.retain_count(), 1); } diff --git a/core-foundation/src/dictionary.rs b/core-foundation/src/dictionary.rs index ba5fc67..df390aa 100644 --- a/core-foundation/src/dictionary.rs +++ b/core-foundation/src/dictionary.rs @@ -16,7 +16,7 @@ use libc::c_void; use std::mem; use std::ptr; -use base::{CFType, CFIndexConvertible, TCFType}; +use base::{CFType, CFIndexConvertible, TCFType, TCFTypeRef}; declare_TCFType!{ @@ -27,10 +27,9 @@ impl_TCFType!(CFDictionary, CFDictionaryRef, CFDictionaryGetTypeID); impl_CFTypeDescription!(CFDictionary); impl CFDictionary { - pub fn from_CFType_pairs(pairs: &[(K, V)]) -> CFDictionary - where K: TCFType, V: TCFType { - let (keys, values): (Vec,Vec) = - pairs.iter() + pub fn from_CFType_pairs(pairs: &[(K, V)]) -> CFDictionary { + let (keys, values): (Vec, Vec) = pairs + .iter() .map(|&(ref key, ref value)| (key.as_CFTypeRef(), value.as_CFTypeRef())) .unzip(); @@ -59,16 +58,14 @@ impl CFDictionary { #[inline] pub fn contains_key(&self, key: *const c_void) -> bool { - unsafe { - CFDictionaryContainsKey(self.0, key) != 0 - } + unsafe { CFDictionaryContainsKey(self.0, key) != 0 } } /// Similar to `contains_key` but acts on a higher level, automatically converting from any /// `TCFType` to the raw pointer of its concrete TypeRef. #[inline] - pub fn contains_key2>(&self, key: &K) -> bool { - self.contains_key(key.as_concrete_TypeRef() as *const c_void) + pub fn contains_key2(&self, key: &K) -> bool { + self.contains_key(key.as_concrete_TypeRef().as_void_ptr()) } #[inline] @@ -86,8 +83,8 @@ impl CFDictionary { /// Similar to `find` but acts on a higher level, automatically converting from any `TCFType` /// to the raw pointer of its concrete TypeRef. #[inline] - pub fn find2>(&self, key: &K) -> Option<*const c_void> { - self.find(key.as_concrete_TypeRef() as *const c_void) + pub fn find2(&self, key: &K) -> Option<*const c_void> { + self.find(key.as_concrete_TypeRef().as_void_ptr()) } /// # Panics @@ -151,8 +148,7 @@ impl CFMutableDictionary { } } - pub fn from_CFType_pairs(pairs: &[(K, V)]) -> CFMutableDictionary - where K: TCFType, V: TCFType { + pub fn from_CFType_pairs(pairs: &[(K, V)]) -> CFMutableDictionary { let result = Self::with_capacity(pairs.len() as _); unsafe { for &(ref key, ref value) in pairs { @@ -186,8 +182,8 @@ impl CFMutableDictionary { /// Similar to `contains_key` but acts on a higher level, automatically converting from any /// `TCFType` to the raw pointer of its concrete TypeRef. #[inline] - pub fn contains_key2>(&self, key: &K) -> bool { - self.contains_key(key.as_concrete_TypeRef() as *const c_void) + pub fn contains_key2(&self, key: &K) -> bool { + self.contains_key(key.as_concrete_TypeRef().as_void_ptr()) } #[inline] @@ -205,8 +201,8 @@ impl CFMutableDictionary { /// Similar to `find` but acts on a higher level, automatically converting from any `TCFType` /// to the raw pointer of its concrete TypeRef. #[inline] - pub fn find2>(&self, key: &K) -> Option<*const c_void> { - self.find(key.as_concrete_TypeRef() as *const c_void) + pub fn find2(&self, key: &K) -> Option<*const c_void> { + self.find(key.as_concrete_TypeRef().as_void_ptr()) } /// # Panics @@ -250,12 +246,12 @@ impl CFMutableDictionary { /// Similar to `add` but acts on a higher level, automatically converting from any `TCFType` /// to the raw pointer of its concrete TypeRef. #[inline] - pub fn add2(&self, key: &K, value: &V) - where K: TCFType<*const RK>, - V: TCFType<*const RV> { + pub fn add2(&self, key: &K, value: &V) { unsafe { - self.add(key.as_concrete_TypeRef() as *const _, - value.as_concrete_TypeRef() as *const _) + self.add( + key.as_concrete_TypeRef().as_void_ptr(), + value.as_concrete_TypeRef().as_void_ptr(), + ) } } @@ -268,12 +264,12 @@ impl CFMutableDictionary { /// Similar to `set` but acts on a higher level, automatically converting from any `TCFType` /// to the raw pointer of its concrete TypeRef. #[inline] - pub fn set2(&self, key: &K, value: &V) - where K: TCFType<*const RK>, - V: TCFType<*const RV> { + pub fn set2(&self, key: &K, value: &V) { unsafe { - self.set(key.as_concrete_TypeRef() as *const c_void, - value.as_concrete_TypeRef() as *const c_void) + self.set( + key.as_concrete_TypeRef().as_void_ptr(), + value.as_concrete_TypeRef().as_void_ptr(), + ) } } @@ -286,12 +282,12 @@ impl CFMutableDictionary { /// Similar to `replace` but acts on a higher level, automatically converting from any `TCFType` /// to the raw pointer of its concrete TypeRef. #[inline] - pub fn replace2(&self, key: &K, value: &V) - where K: TCFType<*const RK>, - V: TCFType<*const RV> { + pub fn replace2(&self, key: &K, value: &V) { unsafe { - self.replace(key.as_concrete_TypeRef() as *const c_void, - value.as_concrete_TypeRef() as *const c_void) + self.replace( + key.as_concrete_TypeRef().as_void_ptr(), + value.as_concrete_TypeRef().as_void_ptr(), + ) } } @@ -304,11 +300,8 @@ impl CFMutableDictionary { /// Similar to `remove` but acts on a higher level, automatically converting from any `TCFType` /// to the raw pointer of its concrete TypeRef. #[inline] - pub fn remove2(&self, key: &K) - where K: TCFType<*const RK> { - unsafe { - self.remove(key.as_concrete_TypeRef() as *const c_void) - } + pub fn remove2(&self, key: &K) { + unsafe { self.remove(key.as_concrete_TypeRef().as_void_ptr()) } } #[inline] @@ -316,3 +309,30 @@ impl CFMutableDictionary { unsafe { CFDictionaryRemoveAllValues(self.0) } } } + + +#[cfg(test)] +pub mod test { + use super::*; + use ::string::CFString; + use ::boolean::{CFBoolean, CFBooleanRef}; + + #[test] + fn dict_find2_and_contains_key2() { + let dict = CFDictionary::from_CFType_pairs(&[ + ( + CFString::from_static_string("hello"), + CFBoolean::true_value(), + ), + ]); + let key = CFString::from_static_string("hello"); + let invalid_key = CFString::from_static_string("foobar"); + + assert!(dict.contains_key2(&key)); + assert!(!dict.contains_key2(&invalid_key)); + + let value = unsafe { CFBoolean::wrap_under_get_rule(dict.find2(&key).unwrap() as CFBooleanRef) }; + assert_eq!(value, CFBoolean::true_value()); + assert_eq!(dict.find2(&invalid_key), None); + } +} diff --git a/core-foundation/src/filedescriptor.rs b/core-foundation/src/filedescriptor.rs index 8794db2..1c3dda0 100644 --- a/core-foundation/src/filedescriptor.rs +++ b/core-foundation/src/filedescriptor.rs @@ -9,16 +9,10 @@ use std::mem; use std::os::unix::io::{AsRawFd, RawFd}; use std::ptr; -pub struct CFFileDescriptor(CFFileDescriptorRef); -impl Drop for CFFileDescriptor { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + CFFileDescriptor, CFFileDescriptorRef } - impl_TCFType!(CFFileDescriptor, CFFileDescriptorRef, CFFileDescriptorGetTypeID); impl CFFileDescriptor { diff --git a/core-foundation/src/lib.rs b/core-foundation/src/lib.rs index 99c969e..7672bdb 100644 --- a/core-foundation/src/lib.rs +++ b/core-foundation/src/lib.rs @@ -33,15 +33,17 @@ macro_rules! declare_TCFType { #[macro_export] macro_rules! impl_TCFType { - ($ty:ident, $raw:ident, $ty_id:ident) => { - impl $crate::base::TCFType<$raw> for $ty { + ($ty:ident, $ty_ref:ident, $ty_id:ident) => { + impl $crate::base::TCFType for $ty { + type Ref = $ty_ref; + #[inline] - fn as_concrete_TypeRef(&self) -> $raw { + fn as_concrete_TypeRef(&self) -> $ty_ref { self.0 } #[inline] - unsafe fn wrap_under_get_rule(reference: $raw) -> $ty { + unsafe fn wrap_under_get_rule(reference: $ty_ref) -> $ty { let reference = ::std::mem::transmute(::core_foundation_sys::base::CFRetain(::std::mem::transmute(reference))); $crate::base::TCFType::wrap_under_create_rule(reference) } @@ -54,7 +56,7 @@ macro_rules! impl_TCFType { } #[inline] - unsafe fn wrap_under_create_rule(obj: $raw) -> $ty { + unsafe fn wrap_under_create_rule(obj: $ty_ref) -> $ty { $ty(obj) } @@ -90,15 +92,17 @@ macro_rules! impl_TCFType { // think of a clean way to have them share code #[macro_export] macro_rules! impl_TCFTypeGeneric { - ($ty:ident, $raw:ident, $ty_id:ident) => { - impl $crate::base::TCFType<$raw> for $ty { + ($ty:ident, $ty_ref:ident, $ty_id:ident) => { + impl $crate::base::TCFType for $ty { + type Ref = $ty_ref; + #[inline] - fn as_concrete_TypeRef(&self) -> $raw { + fn as_concrete_TypeRef(&self) -> $ty_ref { self.0 } #[inline] - unsafe fn wrap_under_get_rule(reference: $raw) -> $ty { + unsafe fn wrap_under_get_rule(reference: $ty_ref) -> $ty { let reference = ::std::mem::transmute(::core_foundation_sys::base::CFRetain(::std::mem::transmute(reference))); $crate::base::TCFType::wrap_under_create_rule(reference) } @@ -111,7 +115,7 @@ macro_rules! impl_TCFTypeGeneric { } #[inline] - unsafe fn wrap_under_create_rule(obj: $raw) -> $ty { + unsafe fn wrap_under_create_rule(obj: $ty_ref) -> $ty { $ty(obj, PhantomData) } diff --git a/core-foundation/src/number.rs b/core-foundation/src/number.rs index d7b6992..75a0078 100644 --- a/core-foundation/src/number.rs +++ b/core-foundation/src/number.rs @@ -51,30 +51,6 @@ impl CFNumber { if ok { Some(value) } else { None } } } - - #[deprecated(note = "please use `CFNumber::from` instead")] - #[inline] - pub fn from_i32(value: i32) -> CFNumber { - CFNumber::from(value) - } - - #[deprecated(note = "please use `CFNumber::from` instead")] - #[inline] - pub fn from_i64(value: i64) -> CFNumber { - Self::from(value) - } - - #[deprecated(note = "please use `CFNumber::from` instead")] - #[inline] - pub fn from_f32(value: f32) -> CFNumber { - Self::from(value) - } - - #[deprecated(note = "please use `CFNumber::from` instead")] - #[inline] - pub fn from_f64(value: f64) -> CFNumber { - Self::from(value) - } } impl From for CFNumber { @@ -132,9 +108,3 @@ impl From for CFNumber { } } } - -/// A convenience function to create CFNumbers. -#[deprecated(note = "please use `CFNumber::from` instead")] -pub fn number(value: i64) -> CFNumber { - CFNumber::from(value) -} diff --git a/core-foundation/src/propertylist.rs b/core-foundation/src/propertylist.rs index d98f2ec..379291f 100644 --- a/core-foundation/src/propertylist.rs +++ b/core-foundation/src/propertylist.rs @@ -16,7 +16,7 @@ use libc::c_void; use error::CFError; use data::CFData; -use base::{CFType, TCFType}; +use base::{CFType, TCFType, TCFTypeRef}; pub use core_foundation_sys::propertylist::*; use core_foundation_sys::error::CFErrorRef; @@ -62,13 +62,13 @@ pub fn create_data(property_list: *const c_void, format: CFPropertyListFormat) - /// Trait for all subclasses of [`CFPropertyList`]. /// /// [`CFPropertyList`]: struct.CFPropertyList.html -pub trait CFPropertyListSubClass: TCFType<*const Raw> { +pub trait CFPropertyListSubClass: TCFType { /// Create an instance of the superclass type [`CFPropertyList`] for this instance. /// /// [`CFPropertyList`]: struct.CFPropertyList.html #[inline] fn to_CFPropertyList(&self) -> CFPropertyList { - unsafe { CFPropertyList::wrap_under_get_rule(self.as_concrete_TypeRef() as *const c_void) } + unsafe { CFPropertyList::wrap_under_get_rule(self.as_concrete_TypeRef().as_void_ptr()) } } /// Equal to [`to_CFPropertyList`], but consumes self and avoids changing the reference count. @@ -76,21 +76,22 @@ pub trait CFPropertyListSubClass: TCFType<*const Raw> { /// [`to_CFPropertyList`]: #method.to_CFPropertyList #[inline] fn into_CFPropertyList(self) -> CFPropertyList - where Self: Sized + where + Self: Sized, { - let reference = self.as_concrete_TypeRef() as *const c_void; + let reference = self.as_concrete_TypeRef().as_void_ptr(); mem::forget(self); unsafe { CFPropertyList::wrap_under_create_rule(reference) } } } -impl CFPropertyListSubClass<::data::__CFData> for ::data::CFData {} -impl CFPropertyListSubClass<::string::__CFString> for ::string::CFString {} -impl CFPropertyListSubClass<::array::__CFArray> for ::array::CFArray {} -impl CFPropertyListSubClass<::dictionary::__CFDictionary> for ::dictionary::CFDictionary {} -impl CFPropertyListSubClass<::date::__CFDate> for ::date::CFDate {} -impl CFPropertyListSubClass<::number::__CFBoolean> for ::boolean::CFBoolean {} -impl CFPropertyListSubClass<::number::__CFNumber> for ::number::CFNumber {} +impl CFPropertyListSubClass for ::data::CFData {} +impl CFPropertyListSubClass for ::string::CFString {} +impl CFPropertyListSubClass for ::array::CFArray {} +impl CFPropertyListSubClass for ::dictionary::CFDictionary {} +impl CFPropertyListSubClass for ::date::CFDate {} +impl CFPropertyListSubClass for ::boolean::CFBoolean {} +impl CFPropertyListSubClass for ::number::CFNumber {} declare_TCFType!{ @@ -132,7 +133,8 @@ impl CFPropertyList { #[inline] pub fn into_CFType(self) -> CFType - where Self: Sized + where + Self: Sized, { let reference = self.as_CFTypeRef(); mem::forget(self); @@ -170,10 +172,8 @@ impl CFPropertyList { /// Returns true if this value is an instance of another type. #[inline] - pub fn instance_of>( - &self, - ) -> bool { - self.type_of() == >::type_id() + pub fn instance_of(&self) -> bool { + self.type_of() == OtherCFType::type_id() } } @@ -209,15 +209,17 @@ impl CFPropertyList { /// // Cast it up to a property list. /// let propertylist: CFPropertyList = string.to_CFPropertyList(); /// // Cast it down again. - /// assert!(propertylist.downcast::<_, CFString>().unwrap().to_string() == "FooBar"); + /// assert!(propertylist.downcast::().unwrap().to_string() == "FooBar"); /// ``` /// /// [`CFPropertyList`]: struct.CFPropertyList.html /// [`Box::downcast`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast - /// [`CFType::downcast`]: ../base/struct.CFType.html#method.downcast - pub fn downcast>(&self) -> Option { - if self.instance_of::<_, T>() { - Some(unsafe { T::wrap_under_get_rule(self.0 as *const Raw) }) + pub fn downcast(&self) -> Option { + if self.instance_of::() { + unsafe { + let subclass_ref = T::Ref::from_void_ptr(self.0); + Some(T::wrap_under_get_rule(subclass_ref)) + } } else { None } @@ -226,11 +228,13 @@ impl CFPropertyList { /// Similar to [`downcast`], but consumes self and can thus avoid touching the retain count. /// /// [`downcast`]: #method.downcast - pub fn downcast_into>(self) -> Option { - if self.instance_of::<_, T>() { - let reference = self.0 as *const Raw; - mem::forget(self); - unsafe { Some(T::wrap_under_create_rule(reference)) } + pub fn downcast_into(self) -> Option { + if self.instance_of::() { + unsafe { + let subclass_ref = T::Ref::from_void_ptr(self.0); + mem::forget(self); + Some(T::wrap_under_create_rule(subclass_ref)) + } } else { None } @@ -288,15 +292,15 @@ pub mod test { #[test] fn downcast_string() { let propertylist = CFString::from_static_string("Bar").to_CFPropertyList(); - assert!(propertylist.downcast::<_, CFString>().unwrap().to_string() == "Bar"); - assert!(propertylist.downcast::<_, CFBoolean>().is_none()); + assert!(propertylist.downcast::().unwrap().to_string() == "Bar"); + assert!(propertylist.downcast::().is_none()); } #[test] fn downcast_boolean() { let propertylist = CFBoolean::true_value().to_CFPropertyList(); - assert!(propertylist.downcast::<_, CFBoolean>().is_some()); - assert!(propertylist.downcast::<_, CFString>().is_none()); + assert!(propertylist.downcast::().is_some()); + assert!(propertylist.downcast::().is_none()); } #[test] @@ -305,7 +309,7 @@ pub mod test { let propertylist = string.to_CFPropertyList(); assert_eq!(string.retain_count(), 2); - assert!(propertylist.downcast_into::<_, CFBoolean>().is_none()); + assert!(propertylist.downcast_into::().is_none()); assert_eq!(string.retain_count(), 1); } @@ -315,7 +319,7 @@ pub mod test { let propertylist = string.to_CFPropertyList(); assert_eq!(string.retain_count(), 2); - let string2 = propertylist.downcast_into::<_, CFString>().unwrap(); + let string2 = propertylist.downcast_into::().unwrap(); assert!(string2.to_string() == "Bar"); assert_eq!(string2.retain_count(), 2); } diff --git a/core-foundation/src/set.rs b/core-foundation/src/set.rs index 0f3df12..fa08aae 100644 --- a/core-foundation/src/set.rs +++ b/core-foundation/src/set.rs @@ -27,7 +27,7 @@ impl_CFTypeDescription!(CFSet); impl CFSet { /// Creates a new set from a list of `CFType` instances. - pub fn from_slice(elems: &[T]) -> CFSet where T: TCFType { + pub fn from_slice(elems: &[T]) -> CFSet where T: TCFType { unsafe { let elems: Vec = elems.iter().map(|elem| elem.as_CFTypeRef()).collect(); let set_ref = CFSetCreate(kCFAllocatorDefault,