Add booleans and refactor to support existential types.
This allows dictionaries to contain values of multiple CFTypes, while remaining type-safe.
This commit is contained in:
@@ -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:CFType> T : CFTypeOps {
|
||||
impl<T:AbstractCFType> 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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+53
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod base;
|
||||
mod boolean;
|
||||
mod dictionary;
|
||||
mod string;
|
||||
mod test;
|
||||
|
||||
+8
-8
@@ -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<K:CFType,V:CFType> {
|
||||
struct CFDictionary<K:AbstractCFType,V:AbstractCFType> {
|
||||
obj: CFDictionaryRef,
|
||||
|
||||
drop {
|
||||
@@ -42,18 +42,18 @@ struct CFDictionary<K:CFType,V:CFType> {
|
||||
}
|
||||
|
||||
mod CFDictionary {
|
||||
fn wrap<K:CFType,V:CFType>(obj: CFDictionaryRef) -> CFDictionary<K,V> {
|
||||
fn wrap<K:AbstractCFType,V:AbstractCFType>(obj: CFDictionaryRef) -> CFDictionary<K,V> {
|
||||
CFDictionary { obj: obj }
|
||||
}
|
||||
|
||||
fn new_dictionary<K:CFType,V:CFType>(pairs: &[(K,V)]) -> CFDictionary<K,V> {
|
||||
fn new_dictionary<K:AbstractCFType,V:AbstractCFType>(pairs: &[(K,V)]) -> CFDictionary<K,V> {
|
||||
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<K:CFType,V:CFType> CFDictionary<K,V> : CFType {
|
||||
pure fn get(&self) -> CFTypeRef {
|
||||
impl<K:AbstractCFType,V:AbstractCFType> CFDictionary<K,V> : AbstractCFType {
|
||||
pure fn as_type_ref(&self) -> CFTypeRef {
|
||||
unsafe {
|
||||
reinterpret_cast(self.obj)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user