diff --git a/base.rs b/base.rs index 72fc9e1..55c09bc 100644 --- a/base.rs +++ b/base.rs @@ -10,17 +10,39 @@ pub type CFAllocatorRef = *__CFAllocator; struct __CFType { private: () } pub type CFTypeRef = *__CFType; -trait CFType { - pure fn get(&self) -> CFTypeRef; +struct CFType { + obj: CFTypeRef, + + drop { + unsafe { + CFRelease(self.obj) + } + } +} + +impl CFType : AbstractCFType { + pure fn as_type_ref(&self) -> CFTypeRef { + self.obj + } +} + +trait AbstractCFType { + pure fn as_type_ref(&self) -> CFTypeRef; } trait CFTypeOps { + fn as_type(self) -> CFType; fn show(&self); } -impl T : CFTypeOps { +impl T : CFTypeOps { + // Consumes self. + fn as_type(self) -> CFType { + CFType { obj: self.as_type_ref() } + } + fn show(&self) { - CFShow(self.get()); + CFShow(self.as_type_ref()); } } diff --git a/boolean.rs b/boolean.rs new file mode 100644 index 0000000..1febd7c --- /dev/null +++ b/boolean.rs @@ -0,0 +1,53 @@ +use base::{AbstractCFType, CFRelease, CFRetain, CFTypeRef}; +use unsafe::reinterpret_cast; + +struct __CFBoolean { private: () } +pub type CFBooleanRef = *__CFBoolean; + +struct CFBoolean { + obj: CFBooleanRef, + + drop { + unsafe { + CFRelease(reinterpret_cast(self.obj)); + } + } +} + +mod CFBoolean { + fn wrap(obj: CFBooleanRef) -> CFBoolean { + CFBoolean { obj: obj } + } + + fn true_value() -> CFBoolean { + unsafe { + let obj = kCFBooleanTrue; + CFRetain(reinterpret_cast(obj)); + return wrap(obj); + } + } + + fn false_value() -> CFBoolean { + unsafe { + let obj = kCFBooleanFalse; + CFRetain(reinterpret_cast(obj)); + return wrap(obj); + } + } +} + +impl CFBoolean : AbstractCFType { + pure fn as_type_ref(&self) -> CFTypeRef { + unsafe { + reinterpret_cast(self.obj) + } + } +} + +#[link_args="-framework CoreFoundation"] +#[nolink] +extern { + const kCFBooleanTrue: CFBooleanRef; + const kCFBooleanFalse: CFBooleanRef; +} + diff --git a/core_foundation.rc b/core_foundation.rc index 1a172a7..7b0ee0c 100644 --- a/core_foundation.rc +++ b/core_foundation.rc @@ -1,4 +1,5 @@ mod base; +mod boolean; mod dictionary; mod string; mod test; diff --git a/dictionary.rs b/dictionary.rs index 0f99a95..b5235be 100644 --- a/dictionary.rs +++ b/dictionary.rs @@ -1,4 +1,4 @@ -use base::{CFAllocatorRef, CFIndex, CFRelease, CFType, CFTypeRef, kCFAllocatorDefault}; +use base::{AbstractCFType, CFAllocatorRef, CFIndex, CFRelease, CFTypeRef, kCFAllocatorDefault}; use dvec::DVec; use libc::c_void; use ptr::to_unsafe_ptr; @@ -31,7 +31,7 @@ pub struct CFDictionaryValueCallBacks { struct __CFDictionary { private: () } pub type CFDictionaryRef = *__CFDictionary; -struct CFDictionary { +struct CFDictionary { obj: CFDictionaryRef, drop { @@ -42,18 +42,18 @@ struct CFDictionary { } mod CFDictionary { - fn wrap(obj: CFDictionaryRef) -> CFDictionary { + fn wrap(obj: CFDictionaryRef) -> CFDictionary { CFDictionary { obj: obj } } - fn new_dictionary(pairs: &[(K,V)]) -> CFDictionary { + fn new_dictionary(pairs: &[(K,V)]) -> CFDictionary { let (keys, values) = (DVec(), DVec()); for pairs.each |pair| { // FIXME: "let" would be much nicer here, but that doesn't work yet. match pair { (ref key, ref value) => { - keys.push(key.get()); - values.push(value.get()); + keys.push(key.as_type_ref()); + values.push(value.as_type_ref()); } } } @@ -76,8 +76,8 @@ mod CFDictionary { } } -impl CFDictionary : CFType { - pure fn get(&self) -> CFTypeRef { +impl CFDictionary : AbstractCFType { + pure fn as_type_ref(&self) -> CFTypeRef { unsafe { reinterpret_cast(self.obj) } diff --git a/string.rs b/string.rs index 8f4069b..ad34e2b 100644 --- a/string.rs +++ b/string.rs @@ -1,5 +1,5 @@ -use base::{Boolean, CFAllocatorRef, CFIndex, CFRelease, CFType, CFTypeRef, kCFAllocatorDefault}; -use base::{kCFAllocatorNull}; +use base::{AbstractCFType, Boolean, CFAllocatorRef, CFIndex, CFRelease, CFTypeRef}; +use base::{kCFAllocatorDefault, kCFAllocatorNull}; use libc::c_char; use unsafe::reinterpret_cast; @@ -40,8 +40,8 @@ mod CFString { } } -impl CFString : CFType { - pure fn get(&self) -> CFTypeRef { +impl CFString : AbstractCFType { + pure fn as_type_ref(&self) -> CFTypeRef { unsafe { reinterpret_cast(self.obj) } diff --git a/test.rs b/test.rs index 71d13a9..edd2a5e 100644 --- a/test.rs +++ b/test.rs @@ -1,11 +1,12 @@ use base::CFTypeOps; +use boolean::CFBoolean; use dictionary::CFDictionary; use string::CFString; fn main() { let d = CFDictionary::new_dictionary([ - (CFString::new_static("Foo"), CFString::new_static("Bar")), - (CFString::new_static("Baz"), CFString::new_static("Boo")) + (CFString::new_static("Foo"), CFString::new_static("Bar").as_type()), + (CFString::new_static("Baz"), CFBoolean::true_value().as_type()) ]); (&d).show(); }