diff --git a/cidre/Cargo.toml b/cidre/Cargo.toml index 46fa2a2c..c0c0076d 100644 --- a/cidre/Cargo.toml +++ b/cidre/Cargo.toml @@ -97,7 +97,7 @@ ci = ["cf", "ns"] cg = ["cf"] # optional io, dispatch, blocks iio = ["cg", "blocks"] objc = ["dep:cidre-macros"] -ns = ["objc"] +ns = ["objc", "cg"] nl = ["ns"] vt = ["cf", "cv", "cg", "cm"] io = ["cf"] diff --git a/cidre/src/cf/base.rs b/cidre/src/cf/base.rs index 9d16cfcd..2b12390f 100644 --- a/cidre/src/cf/base.rs +++ b/cidre/src/cf/base.rs @@ -128,6 +128,20 @@ impl Type { } } +impl std::cmp::PartialEq for Type { + fn eq(&self, other: &Self) -> bool { + self.equal(other) + } +} + +impl std::cmp::Eq for Type {} + +impl std::hash::Hash for Type { + fn hash(&self, state: &mut H) { + state.write_usize(self.hash()); + } +} + impl Debug for Type { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let desc = self.desc(); diff --git a/cidre/src/cf/dictionary.rs b/cidre/src/cf/dictionary.rs index 4a497919..7057120f 100644 --- a/cidre/src/cf/dictionary.rs +++ b/cidre/src/cf/dictionary.rs @@ -540,6 +540,18 @@ where #[repr(transparent)] pub struct DictionaryOfMut(DictionaryMut, marker::PhantomData<(K, V)>); +impl std::ops::Deref for DictionaryOfMut +where + K: arc::Retain, + V: arc::Retain, +{ + type Target = DictionaryOf; + + fn deref(&self) -> &Self::Target { + unsafe { transmute(self) } + } +} + impl DictionaryOfMut where K: arc::Retain, @@ -581,6 +593,10 @@ where transmute(dict) } } + + pub fn copy_mut(&self) -> Option>> { + unsafe { transmute(CFDictionaryCreateMutableCopy(None, 0, &self.0)) } + } } impl arc::Release for DictionaryOfMut @@ -614,6 +630,12 @@ extern "C-unwind" { value_callbacks: Option<&ValueCbs>, ) -> Option>; + fn CFDictionaryCreateMutableCopy( + allocator: Option<&cf::Allocator>, + capacity: cf::Index, + the_dict: &Dictionary, + ) -> Option>; + fn CFDictionaryAddValue(the_dict: &mut DictionaryMut, key: *const c_void, value: *const c_void); fn CFDictionarySetValue(the_dict: &mut DictionaryMut, key: *const c_void, value: *const c_void); fn CFDictionaryReplaceValue( @@ -623,4 +645,5 @@ extern "C-unwind" { ); fn CFDictionaryRemoveValue(the_dict: &mut DictionaryMut, key: *const c_void); fn CFDictionaryRemoveAllValues(the_dict: &mut DictionaryMut); + } diff --git a/cidre/src/cf/string.rs b/cidre/src/cf/string.rs index 494660fd..3e278aa8 100644 --- a/cidre/src/cf/string.rs +++ b/cidre/src/cf/string.rs @@ -1,7 +1,8 @@ use core::fmt; use std::{ - borrow::Cow, + borrow::{Borrow, Cow}, ffi::{c_char, CStr}, + hash::Hash, str::from_utf8_unchecked, }; @@ -529,6 +530,33 @@ impl AsRef for cf::StringMut { } } +impl Borrow for &cf::String { + fn borrow(&self) -> &cf::Type { + self.as_type_ref() + } +} + +impl Borrow for cf::String { + fn borrow(&self) -> &cf::Type { + self.as_type_ref() + } +} + +impl std::cmp::PartialEq for cf::String { + fn eq(&self, other: &Self) -> bool { + self.as_type_ref().eq(other) + } +} + +impl std::cmp::Eq for cf::String {} + +impl std::hash::Hash for cf::String { + fn hash(&self, state: &mut H) { + let hash = self.as_type_ref().hash(); + state.write_usize(hash) + } +} + #[cfg(test)] mod tests { diff --git a/cidre/src/cg.rs b/cidre/src/cg.rs index a6c5fc9b..feed44de 100644 --- a/cidre/src/cg.rs +++ b/cidre/src/cg.rs @@ -65,6 +65,8 @@ pub use font::Glyph; pub use font::Index as FontIndex; mod path; + +#[cfg(feature = "blocks")] pub use path::ApplyBlock as PathApplyBlock; pub use path::Element as PathElement; pub use path::ElementType as PathElementType; diff --git a/cidre/src/dispatch.rs b/cidre/src/dispatch.rs index c9342d58..34b73fd2 100644 --- a/cidre/src/dispatch.rs +++ b/cidre/src/dispatch.rs @@ -23,6 +23,7 @@ pub use queue::QosClass; pub use queue::Queue; pub mod data; +#[cfg(feature = "blocks")] pub use data::Applier as DataApplier; pub use data::Data; diff --git a/cidre/src/dispatch/data.rs b/cidre/src/dispatch/data.rs index 35583bd1..783f512b 100644 --- a/cidre/src/dispatch/data.rs +++ b/cidre/src/dispatch/data.rs @@ -6,6 +6,7 @@ use crate::{arc, define_obj_type, dispatch, ns}; use crate::blocks; #[doc(alias = "dispatch_data_applier_t")] +#[cfg(feature = "blocks")] pub type Applier = blocks::Block bool, Attr>; define_obj_type!( @@ -74,17 +75,20 @@ impl Data { } #[doc(alias = "dispatch_data_create")] + #[cfg(feature = "blocks")] #[inline] pub fn copy_from_slice(data: &[u8]) -> arc::R { unsafe { dispatch_data_create(data.as_ptr(), data.len(), None, None) } } + #[cfg(feature = "blocks")] #[inline] pub fn from_static(bytes: &'static [u8]) -> arc::R { let mut b = blocks::StaticBlock::new0(destructor_noop); unsafe { dispatch_data_create(bytes.as_ptr(), bytes.len(), None, Some(b.as_esc_mut())) } } + #[cfg(feature = "blocks")] #[inline] pub fn with_bytes_no_copy( bytes: *const u8, @@ -107,18 +111,21 @@ impl Data { } extern "C" fn destructor_noop(_ctx: *const c_void) {} +#[cfg(feature = "blocks")] impl From<&'static [u8]> for arc::R { fn from(slice: &'static [u8]) -> arc::R { Data::from_static(slice) } } +#[cfg(feature = "blocks")] impl From<&'static str> for arc::R { fn from(slice: &'static str) -> arc::R { Data::from_static(slice.as_bytes()) } } +#[cfg(feature = "blocks")] impl From> for arc::R { fn from(val: Vec) -> arc::R { let len = val.len(); @@ -135,6 +142,7 @@ impl From> for arc::R { } } +#[cfg(feature = "blocks")] impl From> for arc::R { fn from(val: Box<[u8]>) -> arc::R { let len = val.len(); @@ -155,6 +163,7 @@ impl From> for arc::R { extern "C" { static _dispatch_data_empty: Data; + #[cfg(feature = "blocks")] fn dispatch_data_create( buffer: *const u8, size: usize, diff --git a/cidre/src/dispatch/queue.rs b/cidre/src/dispatch/queue.rs index 6208d225..a7b252c5 100644 --- a/cidre/src/dispatch/queue.rs +++ b/cidre/src/dispatch/queue.rs @@ -365,6 +365,7 @@ extern "C" { #[cfg(feature = "blocks")] fn dispatch_sync(queue: &Queue, block: &mut dispatch::Block); + #[cfg(feature = "blocks")] fn dispatch_async(queue: &Queue, block: &mut dispatch::Block); fn dispatch_async_f(queue: &Queue, context: *mut c_void, work: dispatch::Fn); diff --git a/cidre/src/ns/data.rs b/cidre/src/ns/data.rs index a9cb6e47..34051e03 100644 --- a/cidre/src/ns/data.rs +++ b/cidre/src/ns/data.rs @@ -1,6 +1,9 @@ use std::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut}; -use crate::{arc, blocks, cf, define_obj_type, define_opts, ns, objc}; +use crate::{arc, cf, define_obj_type, define_opts, ns, objc}; + +#[cfg(feature = "blocks")] +use crate::blocks; define_opts!( #[doc(alias = "NSDataReadingOptions")] @@ -164,6 +167,7 @@ impl Data { } /// NSExtendedData +#[cfg(feature = "blocks")] impl Data { #[objc::msg_send(enumerateByteRangesUsingBlock:)] pub fn enumerate_byte_ranges_using_block( diff --git a/cidre/src/ns/file_manager.rs b/cidre/src/ns/file_manager.rs index 6cd58dd5..063121d8 100644 --- a/cidre/src/ns/file_manager.rs +++ b/cidre/src/ns/file_manager.rs @@ -1,4 +1,7 @@ -use crate::{arc, blocks, define_cls, define_obj_type, define_opts, ns, objc, os}; +use crate::{arc, define_cls, define_obj_type, define_opts, ns, objc, os}; + +#[cfg(feature = "blocks")] +use crate::blocks; define_obj_type!( #[doc(alias = "NSFileAttributeKey")] @@ -294,6 +297,7 @@ impl FileManager { options: ns::VolumeEnumOpts, ) -> arc::R>; + #[cfg(feature = "blocks")] #[objc::msg_send(unmountVolumeAtURL:options:completionHandler:)] pub fn unmount_volume_at_url_ch_block( &self, diff --git a/cidre/src/ns/operation.rs b/cidre/src/ns/operation.rs index 31b7d1b3..754af7aa 100644 --- a/cidre/src/ns/operation.rs +++ b/cidre/src/ns/operation.rs @@ -1,4 +1,7 @@ -use crate::{arc, define_cls, define_obj_type, dispatch, ns, objc}; +use crate::{arc, define_cls, define_obj_type, ns, objc}; + +#[cfg(feature = "dispatch")] +use crate::dispatch; #[cfg(feature = "blocks")] use crate::blocks; @@ -145,9 +148,11 @@ impl OpQueue { #[objc::msg_send(cancelAllOperations)] pub fn cancel_all_ops(&mut self); + #[cfg(feature = "dispatch")] #[objc::msg_send(underlyingQueue)] pub fn underlying_queue(&self) -> Option>; + #[cfg(feature = "dispatch")] #[objc::msg_send(setUnderlyingQueue:)] pub fn set_underlying_queue(&mut self, val: Option<&dispatch::Queue>);