Skip to content

Commit 3e0e109

Browse files
committed
Add CFBoolean and CFNumber helpers
1 parent 6d82a79 commit 3e0e109

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

framework-crates/objc2-core-foundation/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ mod cf_type;
2626
mod generated;
2727
#[cfg(feature = "CFCGTypes")]
2828
mod geometry;
29+
#[cfg(feature = "CFNumber")]
30+
mod number;
2931
mod retained;
3032
#[cfg(all(feature = "CFBase", feature = "CFString"))]
3133
mod string;
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#![cfg(feature = "CFBase")]
2+
use crate::{
3+
kCFBooleanFalse, kCFBooleanTrue, CFBoolean, CFBooleanGetValue, CFNumber, CFNumberCreate,
4+
CFNumberGetValue, CFNumberType, CFRetained,
5+
};
6+
7+
impl CFBoolean {
8+
pub fn new(value: bool) -> &'static CFBoolean {
9+
if value {
10+
unsafe { kCFBooleanTrue }.unwrap()
11+
} else {
12+
unsafe { kCFBooleanFalse }.unwrap()
13+
}
14+
}
15+
16+
pub fn as_bool(&self) -> bool {
17+
unsafe { CFBooleanGetValue(self) != 0 }
18+
}
19+
}
20+
21+
macro_rules! def_new_fn {
22+
{$(
23+
$(#[$($m:meta)*])*
24+
($fn_name:ident($fn_inp:ty); $type:ident),
25+
)*} => {$(
26+
$(#[$($m)*])*
27+
#[inline]
28+
pub fn $fn_name(val: $fn_inp) -> CFRetained<Self> {
29+
let ptr: *const $fn_inp = &val;
30+
unsafe { CFNumberCreate(None, CFNumberType::$type, ptr.cast()).expect("failed creating CFNumber") }
31+
}
32+
)*}
33+
}
34+
35+
impl CFNumber {
36+
def_new_fn! {
37+
(new_i8(i8); SInt8Type),
38+
(new_i16(i16); SInt16Type),
39+
(new_i32(i32); SInt32Type),
40+
(new_i64(i64); SInt64Type),
41+
(new_isize(isize); NSIntegerType),
42+
43+
(new_f32(f32); Float32Type),
44+
(new_f64(f64); Float64Type),
45+
}
46+
47+
#[cfg(feature = "CFCGTypes")]
48+
#[inline]
49+
pub fn new_cgfloat(val: crate::CGFloat) -> CFRetained<Self> {
50+
#[cfg(not(target_pointer_width = "64"))]
51+
{
52+
Self::new_f32(val)
53+
}
54+
#[cfg(target_pointer_width = "64")]
55+
{
56+
Self::new_f64(val)
57+
}
58+
}
59+
}
60+
61+
macro_rules! def_get_fn {
62+
{$(
63+
$(#[$($m:meta)*])*
64+
($fn_name:ident -> $fn_ret:ty; $type:ident),
65+
)*} => {$(
66+
$(#[$($m)*])*
67+
#[inline]
68+
pub fn $fn_name(&self) -> Option<$fn_ret> {
69+
let mut value: $fn_ret = <$fn_ret>::default();
70+
let ptr: *mut$fn_ret = &mut value;
71+
let ret = unsafe { CFNumberGetValue(self, CFNumberType::$type, ptr.cast()) };
72+
if ret != 0 {
73+
Some(value)
74+
} else {
75+
None
76+
}
77+
}
78+
)*}
79+
}
80+
81+
impl CFNumber {
82+
def_get_fn! {
83+
(as_i8 -> i8; SInt8Type),
84+
(as_i16 -> i16; SInt16Type),
85+
(as_i32 -> i32; SInt32Type),
86+
(as_i64 -> i64; SInt64Type),
87+
(as_isize -> isize; NSIntegerType),
88+
89+
(as_f32 -> f32; Float32Type),
90+
(as_f64 -> f64; Float64Type),
91+
}
92+
93+
#[cfg(feature = "CFCGTypes")]
94+
#[inline]
95+
pub fn as_cgfloat(&self) -> Option<crate::CGFloat> {
96+
#[cfg(not(target_pointer_width = "64"))]
97+
{
98+
self.as_f32()
99+
}
100+
#[cfg(target_pointer_width = "64")]
101+
{
102+
self.as_f64()
103+
}
104+
}
105+
}
106+
107+
#[cfg(test)]
108+
mod tests {
109+
use super::*;
110+
111+
#[test]
112+
fn to_from_bool() {
113+
let cffalse = CFBoolean::new(false);
114+
let cftrue = CFBoolean::new(true);
115+
assert_ne!(cffalse, cftrue);
116+
assert_eq!(cftrue, CFBoolean::new(true));
117+
assert_eq!(cffalse, CFBoolean::new(false));
118+
assert!(!cffalse.as_bool());
119+
assert!(cftrue.as_bool());
120+
}
121+
122+
#[test]
123+
fn to_from_number() {
124+
let n = CFNumber::new_i32(442);
125+
assert_eq!(n.as_i8(), Some(442i32 as i8));
126+
assert_eq!(n.as_i16(), Some(442));
127+
assert_eq!(n.as_i32(), Some(442));
128+
assert_eq!(n.as_i64(), Some(442));
129+
assert_eq!(n.as_f32(), Some(442.0));
130+
assert_eq!(n.as_f64(), Some(442.0));
131+
}
132+
}

0 commit comments

Comments
 (0)