// Copyright 2013 The Servo Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms.
//! Dictionaries of key-value pairs.
pubuse core_foundation_sys::dictionary::*;
use core_foundation_sys::base::{kCFAllocatorDefault, CFRelease, CFTypeRef}; use std::marker::PhantomData; use std::mem; use std::os::raw::c_void; use std::ptr;
// consume the type parameters with PhantomDatas pubstruct CFDictionary<K = *const c_void, V = *const c_void>(
CFDictionaryRef,
PhantomData<K>,
PhantomData<V>,
);
impl<K, V> Drop for CFDictionary<K, V> { fn drop(&mutself) { unsafe { CFRelease(self.as_CFTypeRef()) }
}
}
/// Returns a `CFMutableDictionary` pointing to the same underlying dictionary as this immutable one. /// This should only be used when the underlying dictionary is mutable. #[inline] pubunsafefn to_mutable(&self) -> CFMutableDictionary<K, V> {
CFMutableDictionary::wrap_under_get_rule(self.0as CFMutableDictionaryRef)
}
/// Returns the same dictionary, but with the types reset to void pointers. /// Equal to `to_untyped`, but is faster since it does not increment the retain count. #[inline] pubfn into_untyped(self) -> CFDictionary { let reference = self.0;
mem::forget(self); unsafe { CFDictionary::wrap_under_create_rule(reference) }
}
/// # Panics /// /// Panics if the key is not present in the dictionary. Use `find` to get an `Option` instead /// of panicking. #[inline] pubfn get<T: ToVoid<K>>(&self, key: T) -> ItemRef<'_, V> where
V: FromVoid,
K: ToVoid<K>,
{ let ptr = key.to_void(); self.find(key)
.unwrap_or_else(|| panic!("No entry found for key {:p}", ptr))
}
// consume the type parameters with PhantomDatas pubstruct CFMutableDictionary<K = *const c_void, V = *const c_void>(
CFMutableDictionaryRef,
PhantomData<K>,
PhantomData<V>,
);
impl<K, V> Drop for CFMutableDictionary<K, V> { fn drop(&mutself) { unsafe { CFRelease(self.as_CFTypeRef()) }
}
}
pubfn copy_with_capacity(&self, capacity: isize) -> Self { unsafe { let dictionary_ref =
CFDictionaryCreateMutableCopy(kCFAllocatorDefault, capacity as _, self.0);
TCFType::wrap_under_get_rule(dictionary_ref)
}
}
pubfn from_CFType_pairs(pairs: &[(K, V)]) -> CFMutableDictionary<K, V> where
K: ToVoid<K>,
V: ToVoid<V>,
{ letmut result = Self::with_capacity(pairs.len() as _); for (key, value) in pairs {
result.add(key, value);
}
result
}
/// Returns the same dictionary, but with the types reset to void pointers. /// Equal to `to_untyped`, but is faster since it does not increment the retain count. #[inline] pubfn into_untyped(self) -> CFMutableDictionary { let reference = self.0;
mem::forget(self); unsafe { CFMutableDictionary::wrap_under_create_rule(reference) }
}
/// Returns a `CFDictionary` pointing to the same underlying dictionary as this mutable one. #[inline] pubfn to_immutable(&self) -> CFDictionary<K, V> { unsafe { CFDictionary::wrap_under_get_rule(self.0) }
}
/// # Panics /// /// Panics if the key is not present in the dictionary. Use `find` to get an `Option` instead /// of panicking. #[inline] pubfn get<'a>(&'a self, key: &K) -> ItemRef<'a, V> where
V: FromVoid,
K: ToVoid<K>,
{ let ptr = key.to_void(); self.find(key)
.unwrap_or_else(|| panic!("No entry found for key {:p}", ptr))
}
/// Adds the key-value pair to the dictionary if no such key already exist. #[inline] pubfn add(&mutself, key: &K, value: &V) where
K: ToVoid<K>,
V: ToVoid<V>,
{ unsafe { CFDictionaryAddValue(self.0, key.to_void(), value.to_void()) }
}
/// Sets the value of the key in the dictionary. #[inline] pubfn set(&mutself, key: K, value: V) where
K: ToVoid<K>,
V: ToVoid<V>,
{ unsafe { CFDictionarySetValue(self.0, key.to_void(), value.to_void()) }
}
/// Replaces the value of the key in the dictionary. #[inline] pubfn replace(&mutself, key: K, value: V) where
K: ToVoid<K>,
V: ToVoid<V>,
{ unsafe { CFDictionaryReplaceValue(self.0, key.to_void(), value.to_void()) }
}
/// Removes the value of the key from the dictionary. #[inline] pubfn remove(&mutself, key: K) where
K: ToVoid<K>,
{ unsafe { CFDictionaryRemoveValue(self.0, key.to_void()) }
}
impl<'a, K, V> From<&'a CFDictionary<K, V>> for CFMutableDictionary<K, V> { /// Creates a new mutable dictionary with the key-value pairs from another dictionary. /// The capacity of the new mutable dictionary is not limited. fn from(dict: &'a CFDictionary<K, V>) -> Self { unsafe { let mut_dict_ref = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, dict.0);
TCFType::wrap_under_create_rule(mut_dict_ref)
}
}
}
#[cfg(test)] pubmod test { usesuper::*; usecrate::base::{CFType, TCFType}; usecrate::boolean::CFBoolean; usecrate::number::CFNumber; usecrate::string::CFString;
#[test] fn dictionary() { let bar = CFString::from_static_string("Bar"); let baz = CFString::from_static_string("Baz"); let boo = CFString::from_static_string("Boo"); let foo = CFString::from_static_string("Foo"); let tru = CFBoolean::true_value(); let n42 = CFNumber::from(42);
let d = CFDictionary::from_CFType_pairs(&[
(bar.as_CFType(), boo.as_CFType()),
(baz.as_CFType(), tru.as_CFType()),
(foo.as_CFType(), n42.as_CFType()),
]);
#[test] fn mutable_dictionary() { let bar = CFString::from_static_string("Bar"); let baz = CFString::from_static_string("Baz"); let boo = CFString::from_static_string("Boo"); let foo = CFString::from_static_string("Foo"); let tru = CFBoolean::true_value(); let n42 = CFNumber::from(42);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.