diff --git a/core-foundation/src/base.rs b/core-foundation/src/base.rs index 3d945e9..eb05e34 100644 --- a/core-foundation/src/base.rs +++ b/core-foundation/src/base.rs @@ -30,8 +30,10 @@ impl CFIndexConvertible for usize { } } -/// Superclass of all Core Foundation objects. -pub struct CFType(CFTypeRef); +declare_TCFType!{ + /// Superclass of all Core Foundation objects. + CFType, CFTypeRef +} impl fmt::Debug for CFType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -60,25 +62,7 @@ impl PartialEq for CFType { } } -impl Drop for CFType { - fn drop(&mut self) { - unsafe { - CFRelease(self.0) - } - } -} - -/// An allocator for Core Foundation objects. -pub struct CFAllocator(CFAllocatorRef); - -impl Drop for CFAllocator { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } -} - +declare_TCFType!(CFAllocator, CFAllocatorRef); impl_TCFType!(CFAllocator, CFAllocatorRef, CFAllocatorGetTypeID); impl CFAllocator { diff --git a/core-foundation/src/boolean.rs b/core-foundation/src/boolean.rs index e843467..14a9996 100644 --- a/core-foundation/src/boolean.rs +++ b/core-foundation/src/boolean.rs @@ -14,19 +14,13 @@ pub use core_foundation_sys::number::{CFBooleanRef, CFBooleanGetTypeID, kCFBoole use base::TCFType; -/// A Boolean type. -/// -/// FIXME(pcwalton): Should be a newtype struct, but that fails due to a Rust compiler bug. -pub struct CFBoolean(CFBooleanRef); -impl Drop for CFBoolean { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + /// A Boolean type. + /// + /// FIXME(pcwalton): Should be a newtype struct, but that fails due to a Rust compiler bug. + CFBoolean, CFBooleanRef } - impl_TCFType!(CFBoolean, CFBooleanRef, CFBooleanGetTypeID); impl_CFTypeDescription!(CFBoolean); diff --git a/core-foundation/src/bundle.rs b/core-foundation/src/bundle.rs index 4d75c30..4b50623 100644 --- a/core-foundation/src/bundle.rs +++ b/core-foundation/src/bundle.rs @@ -16,16 +16,12 @@ use base::TCFType; use url::CFURL; use dictionary::CFDictionary; -/// A Bundle type. -pub struct CFBundle(CFBundleRef); -impl Drop for CFBundle { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + /// A Bundle type. + CFBundle, CFBundleRef } +impl_TCFType!(CFBundle, CFBundleRef, CFBundleGetTypeID); impl CFBundle { pub fn new(bundleURL: CFURL) -> Option { @@ -76,7 +72,6 @@ impl CFBundle { } } -impl_TCFType!(CFBundle, CFBundleRef, CFBundleGetTypeID); #[test] fn safari_executable_url() { diff --git a/core-foundation/src/data.rs b/core-foundation/src/data.rs index baa95f2..6615b9a 100644 --- a/core-foundation/src/data.rs +++ b/core-foundation/src/data.rs @@ -17,17 +17,11 @@ use std::slice; use base::{CFIndexConvertible, TCFType}; -/// A byte buffer. -pub struct CFData(CFDataRef); -impl Drop for CFData { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + /// A byte buffer. + CFData, CFDataRef } - impl_TCFType!(CFData, CFDataRef, CFDataGetTypeID); impl_CFTypeDescription!(CFData); diff --git a/core-foundation/src/date.rs b/core-foundation/src/date.rs index ee78cf8..17a49b5 100644 --- a/core-foundation/src/date.rs +++ b/core-foundation/src/date.rs @@ -17,17 +17,11 @@ use base::TCFType; #[cfg(feature = "with-chrono")] use chrono::NaiveDateTime; -/// A date. -pub struct CFDate(CFDateRef); -impl Drop for CFDate { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + /// A date. + CFDate, CFDateRef } - impl_TCFType!(CFDate, CFDateRef, CFDateGetTypeID); impl_CFTypeDescription!(CFDate); impl_CFComparison!(CFDate, CFDateCompare); diff --git a/core-foundation/src/dictionary.rs b/core-foundation/src/dictionary.rs index 5d4a12b..c4c2f7c 100644 --- a/core-foundation/src/dictionary.rs +++ b/core-foundation/src/dictionary.rs @@ -18,17 +18,11 @@ use std::ptr; use base::{CFType, CFIndexConvertible, TCFType}; -/// An immutable dictionary of key-value pairs. -pub struct CFDictionary(CFDictionaryRef); -impl Drop for CFDictionary { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + /// An immutable dictionary of key-value pairs. + CFDictionary, CFDictionaryRef } - impl_TCFType!(CFDictionary, CFDictionaryRef, CFDictionaryGetTypeID); impl_CFTypeDescription!(CFDictionary); diff --git a/core-foundation/src/error.rs b/core-foundation/src/error.rs index af9b26f..39842e6 100644 --- a/core-foundation/src/error.rs +++ b/core-foundation/src/error.rs @@ -17,17 +17,11 @@ use std::fmt; use base::{CFIndex, TCFType}; use string::CFString; -/// An error value. -pub struct CFError(CFErrorRef); -impl Drop for CFError { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + /// An error value. + CFError, CFErrorRef } - impl_TCFType!(CFError, CFErrorRef, CFErrorGetTypeID); impl fmt::Debug for CFError { diff --git a/core-foundation/src/lib.rs b/core-foundation/src/lib.rs index f1f8b4f..30de654 100644 --- a/core-foundation/src/lib.rs +++ b/core-foundation/src/lib.rs @@ -14,6 +14,23 @@ extern crate libc; #[cfg(feature = "with-chrono")] extern crate chrono; +#[macro_export] +macro_rules! declare_TCFType { + ( + $(#[$doc:meta])* + $ty:ident, $raw:ident + ) => { + $(#[$doc])* + pub struct $ty($raw); + + impl Drop for $ty { + fn drop(&mut self) { + unsafe { CFRelease(self.as_CFTypeRef()) } + } + } + } +} + #[macro_export] macro_rules! impl_TCFType { ($ty:ident, $raw:ident, $ty_id:ident) => { diff --git a/core-foundation/src/number.rs b/core-foundation/src/number.rs index cd02635..d7b6992 100644 --- a/core-foundation/src/number.rs +++ b/core-foundation/src/number.rs @@ -13,19 +13,13 @@ use core_foundation_sys::base::{CFRelease, kCFAllocatorDefault}; pub use core_foundation_sys::number::*; use std::mem; -use base::{TCFType}; +use base::TCFType; -/// An immutable numeric value. -pub struct CFNumber(CFNumberRef); -impl Drop for CFNumber { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + /// An immutable numeric value. + CFNumber, CFNumberRef } - impl_TCFType!(CFNumber, CFNumberRef, CFNumberGetTypeID); impl_CFTypeDescription!(CFNumber); impl_CFComparison!(CFNumber, CFNumberCompare); diff --git a/core-foundation/src/propertylist.rs b/core-foundation/src/propertylist.rs index b8d5e02..ff89e0f 100644 --- a/core-foundation/src/propertylist.rs +++ b/core-foundation/src/propertylist.rs @@ -79,28 +79,25 @@ impl CFPropertyListSubClass<::date::__CFDate> for ::date::CFDate {} impl CFPropertyListSubClass<::number::__CFBoolean> for ::boolean::CFBoolean {} impl CFPropertyListSubClass<::number::__CFNumber> for ::number::CFNumber {} -/// A CFPropertyList struct. This is superclass to [`CFData`], [`CFString`], [`CFArray`], -/// [`CFDictionary`], [`CFDate`], [`CFBoolean`], and [`CFNumber`]. -/// -/// This superclass type does not have its own `CFTypeID`, instead each instance has the `CFTypeID` -/// of the subclass it is an instance of. Thus, this type cannot implement the [`TCFType`] trait, -/// since it cannot implement the static [`TCFType::type_id()`] method. -/// -/// [`CFData`]: ../data/struct.CFData.html -/// [`CFString`]: ../string/struct.CFString.html -/// [`CFArray`]: ../array/struct.CFArray.html -/// [`CFDictionary`]: ../dictionary/struct.CFDictionary.html -/// [`CFDate`]: ../date/struct.CFDate.html -/// [`CFBoolean`]: ../boolean/struct.CFBoolean.html -/// [`CFNumber`]: ../number/struct.CFNumber.html -/// [`TCFType`]: ../base/trait.TCFType.html -/// [`TCFType::type_id()`]: ../base/trait.TCFType.html#method.type_of -pub struct CFPropertyList(CFPropertyListRef); -impl Drop for CFPropertyList { - fn drop(&mut self) { - unsafe { CFRelease(self.as_CFTypeRef()) } - } +declare_TCFType!{ + /// A CFPropertyList struct. This is superclass to [`CFData`], [`CFString`], [`CFArray`], + /// [`CFDictionary`], [`CFDate`], [`CFBoolean`], and [`CFNumber`]. + /// + /// This superclass type does not have its own `CFTypeID`, instead each instance has the `CFTypeID` + /// of the subclass it is an instance of. Thus, this type cannot implement the [`TCFType`] trait, + /// since it cannot implement the static [`TCFType::type_id()`] method. + /// + /// [`CFData`]: ../data/struct.CFData.html + /// [`CFString`]: ../string/struct.CFString.html + /// [`CFArray`]: ../array/struct.CFArray.html + /// [`CFDictionary`]: ../dictionary/struct.CFDictionary.html + /// [`CFDate`]: ../date/struct.CFDate.html + /// [`CFBoolean`]: ../boolean/struct.CFBoolean.html + /// [`CFNumber`]: ../number/struct.CFNumber.html + /// [`TCFType`]: ../base/trait.TCFType.html + /// [`TCFType::type_id()`]: ../base/trait.TCFType.html#method.type_of + CFPropertyList, CFPropertyListRef } impl CFPropertyList { diff --git a/core-foundation/src/runloop.rs b/core-foundation/src/runloop.rs index 887303b..5a12c21 100644 --- a/core-foundation/src/runloop.rs +++ b/core-foundation/src/runloop.rs @@ -20,16 +20,8 @@ use string::{CFString}; pub type CFRunLoopMode = CFStringRef; -pub struct CFRunLoop(CFRunLoopRef); - -impl Drop for CFRunLoop { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } -} +declare_TCFType!(CFRunLoop, CFRunLoopRef); impl_TCFType!(CFRunLoop, CFRunLoopRef, CFRunLoopGetTypeID); impl_CFTypeDescription!(CFRunLoop); @@ -128,16 +120,8 @@ impl CFRunLoop { } -pub struct CFRunLoopTimer(CFRunLoopTimerRef); - -impl Drop for CFRunLoopTimer { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } -} +declare_TCFType!(CFRunLoopTimer, CFRunLoopTimerRef); impl_TCFType!(CFRunLoopTimer, CFRunLoopTimerRef, CFRunLoopTimerGetTypeID); impl CFRunLoopTimer { @@ -150,29 +134,10 @@ impl CFRunLoopTimer { } -pub struct CFRunLoopSource(CFRunLoopSourceRef); - -impl Drop for CFRunLoopSource { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } -} - +declare_TCFType!(CFRunLoopSource, CFRunLoopSourceRef); impl_TCFType!(CFRunLoopSource, CFRunLoopSourceRef, CFRunLoopSourceGetTypeID); - -pub struct CFRunLoopObserver(CFRunLoopObserverRef); - -impl Drop for CFRunLoopObserver { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } -} - +declare_TCFType!(CFRunLoopObserver, CFRunLoopObserverRef); impl_TCFType!(CFRunLoopObserver, CFRunLoopObserverRef, CFRunLoopObserverGetTypeID); #[cfg(test)] diff --git a/core-foundation/src/set.rs b/core-foundation/src/set.rs index 4dab26f..0f3df12 100644 --- a/core-foundation/src/set.rs +++ b/core-foundation/src/set.rs @@ -17,17 +17,11 @@ use base::{CFIndexConvertible, TCFType}; use std::mem; -/// An immutable bag of elements. -pub struct CFSet(CFSetRef); -impl Drop for CFSet { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + /// An immutable bag of elements. + CFSet, CFSetRef } - impl_TCFType!(CFSet, CFSetRef, CFSetGetTypeID); impl_CFTypeDescription!(CFSet); diff --git a/core-foundation/src/string.rs b/core-foundation/src/string.rs index 5026b71..06cfd56 100644 --- a/core-foundation/src/string.rs +++ b/core-foundation/src/string.rs @@ -20,17 +20,11 @@ use std::str::{self, FromStr}; use std::ptr; use std::ffi::CStr; -/// An immutable string in one of a variety of encodings. -pub struct CFString(CFStringRef); -impl Drop for CFString { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + /// An immutable string in one of a variety of encodings. + CFString, CFStringRef } - impl_TCFType!(CFString, CFStringRef, CFStringGetTypeID); impl FromStr for CFString { diff --git a/core-foundation/src/timezone.rs b/core-foundation/src/timezone.rs index 5e2650d..596361b 100644 --- a/core-foundation/src/timezone.rs +++ b/core-foundation/src/timezone.rs @@ -18,17 +18,11 @@ use date::{CFDate, CFTimeInterval}; #[cfg(feature = "with-chrono")] use chrono::{FixedOffset, NaiveDateTime}; -/// A time zone. -pub struct CFTimeZone(CFTimeZoneRef); -impl Drop for CFTimeZone { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType!{ + /// A time zone. + CFTimeZone, CFTimeZoneRef } - impl_TCFType!(CFTimeZone, CFTimeZoneRef, CFTimeZoneGetTypeID); impl_CFTypeDescription!(CFTimeZone); diff --git a/core-foundation/src/url.rs b/core-foundation/src/url.rs index 85e05f3..ad77d4a 100644 --- a/core-foundation/src/url.rs +++ b/core-foundation/src/url.rs @@ -27,16 +27,8 @@ use std::os::unix::ffi::OsStrExt; #[cfg(unix)] use std::ffi::OsStr; -pub struct CFURL(CFURLRef); - -impl Drop for CFURL { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } -} +declare_TCFType!(CFURL, CFURLRef); impl_TCFType!(CFURL, CFURLRef, CFURLGetTypeID); impl fmt::Debug for CFURL { diff --git a/core-foundation/src/uuid.rs b/core-foundation/src/uuid.rs index 3396c16..4aef132 100644 --- a/core-foundation/src/uuid.rs +++ b/core-foundation/src/uuid.rs @@ -20,17 +20,11 @@ use base::TCFType; #[cfg(feature = "with-uuid")] use self::uuid::Uuid; -/// A UUID. -pub struct CFUUID(CFUUIDRef); -impl Drop for CFUUID { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } +declare_TCFType! { + /// A UUID. + CFUUID, CFUUIDRef } - impl_TCFType!(CFUUID, CFUUIDRef, CFUUIDGetTypeID); impl_CFTypeDescription!(CFUUID);