1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
extern crate file_metadata_mditem_macros; use std::marker::PhantomData; use core_foundation_sys::base::{TCFTypeRef, CFTypeID}; use core_foundation::string::{CFString, CFStringRef}; use core_foundation::array::{CFArray, CFArrayRef}; use core_foundation::base::TCFType; use libc::c_void; #[repr(C)] pub struct __MDItemRef(c_void); pub type MDItemRef = *const __MDItemRef; #[link(name = "CoreServices", kind = "framework")] extern "C" { fn MDItemCopyAttribute(item: MDItemRef, name: CFStringRef) -> *const c_void; fn MDItemCopyAttributeNames(item: MDItemRef) -> CFArrayRef; fn MDItemGetTypeID() -> CFTypeID; } pub struct Attribute<T> { pub key_getter: fn() -> CFStringRef, pub phantom: PhantomData<T> } impl<T: TCFType> Attribute<T> { pub fn key(&self) -> CFStringRef { (self.key_getter)() } } pub mod attributes; declare_TCFType!{ MDItem, MDItemRef } impl_TCFType!(MDItem, MDItemRef, MDItemGetTypeID); impl MDItem { pub fn attributes(&self) -> CFArray<CFString> { unsafe { TCFType::wrap_under_create_rule(MDItemCopyAttributeNames(self.0)) } } #[inline] pub fn get<T>(&self, attr: Attribute<T>) -> Option<T> where T: TCFType { let value = unsafe { MDItemCopyAttribute(self.0, attr.key()) }; if value.is_null() { None } else { Some(unsafe { T::wrap_under_create_rule(T::Ref::from_void_ptr(value)) }) } } } #[cfg(test)] mod tests { use super::attributes::URL; use core_foundation::string::CFString; use core_foundation::base::TCFType; #[test] fn it_works() { println!("{:#?}", unsafe { CFString::wrap_under_get_rule(URL.key()) }); } }