Add macro that declare CF types with Drop impl

This commit is contained in:
Linus Färnstrand
2018-01-14 13:21:50 +01:00
parent 3a8e10cb4f
commit 4fc21d970b
16 changed files with 82 additions and 192 deletions
+5 -21
View File
@@ -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 {
+5 -11
View File
@@ -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);
+4 -9
View File
@@ -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<CFBundle> {
@@ -76,7 +72,6 @@ impl CFBundle {
}
}
impl_TCFType!(CFBundle, CFBundleRef, CFBundleGetTypeID);
#[test]
fn safari_executable_url() {
+3 -9
View File
@@ -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);
+3 -9
View File
@@ -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);
+3 -9
View File
@@ -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);
+3 -9
View File
@@ -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 {
+17
View File
@@ -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) => {
+4 -10
View File
@@ -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);
+18 -21
View File
@@ -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 {
+4 -39
View File
@@ -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)]
+3 -9
View File
@@ -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);
+3 -9
View File
@@ -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 {
+3 -9
View File
@@ -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);
+1 -9
View File
@@ -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 {
+3 -9
View File
@@ -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);