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:
Patrick Walton
2012-08-30 18:43:43 -07:00
parent 0225d54195
commit 4d402a7937
6 changed files with 95 additions and 18 deletions
+26 -4
View File
@@ -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
View File
@@ -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
View File
@@ -1,4 +1,5 @@
mod base;
mod boolean;
mod dictionary;
mod string;
mod test;
+8 -8
View File
@@ -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)
}
+4 -4
View File
@@ -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)
}
+3 -2
View File
@@ -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();
}