use objc2_core_foundation::{CFArray, CFDictionary, CFNumber, CFRetained, CFString, CFType};
use std::ffi::c_void;
use std::ptr::NonNull;
pub type Cf = CFRetained<CFType>;
pub fn string(value: &str) -> Cf {
CFString::from_str(value).into()
}
pub fn number(value: f64) -> Cf {
CFNumber::new_f64(value).into()
}
pub fn dictionary(entries: &[(&str, Cf)]) -> CFRetained<CFDictionary> {
let keys: Vec<CFRetained<CFString>> =
entries.iter().map(|(k, _)| CFString::from_str(k)).collect();
let key_refs: Vec<&CFString> = keys.iter().map(|k| &**k).collect();
let value_refs: Vec<&CFType> = entries.iter().map(|(_, v)| &**v).collect();
let dict = CFDictionary::<CFString, CFType>::from_slices(&key_refs, &value_refs);
unsafe { CFRetained::cast_unchecked::<CFDictionary>(dict) }
}
pub fn array(values: &[Cf]) -> CFRetained<CFArray> {
let array = CFArray::<CFType>::from_retained_objects(values);
unsafe { CFRetained::cast_unchecked::<CFArray>(array) }
}
pub unsafe fn retain(raw: *const c_void) {
if let Some(ptr) = NonNull::new(raw.cast_mut().cast::<CFType>()) {
let _ = CFRetained::into_raw(unsafe { CFRetained::retain(ptr) });
}
}
pub unsafe fn release(raw: *const c_void) {
if let Some(ptr) = NonNull::new(raw.cast_mut().cast::<CFType>()) {
drop(unsafe { CFRetained::from_raw(ptr) });
}
}