1use std::ffi::{c_char, c_void};
30use std::ptr::NonNull;
31
32use mtl_sys::{class, msg_send_0, msg_send_1, msg_send_2, sel};
33
34use crate::objc_runtime::ComparisonResult;
35use crate::object::{Copying, Referencing};
36use crate::string::String;
37use crate::types::{Integer, UInteger};
38
39#[repr(transparent)]
43#[derive(Clone)]
44pub struct Value(NonNull<c_void>);
45
46impl Value {
47 #[inline]
51 pub fn value(value: *const c_void, obj_c_type: *const c_char) -> Option<Self> {
52 unsafe {
53 let ptr: *mut c_void = msg_send_2(
54 class!(NSValue).as_ptr(),
55 sel!(valueWithBytes:objCType:),
56 value,
57 obj_c_type,
58 );
59 Self::from_ptr(ptr)
60 }
61 }
62
63 #[inline]
67 pub fn value_with_pointer(pointer: *const c_void) -> Option<Self> {
68 unsafe {
69 let ptr: *mut c_void =
70 msg_send_1(class!(NSValue).as_ptr(), sel!(valueWithPointer:), pointer);
71 Self::from_ptr(ptr)
72 }
73 }
74
75 #[inline]
79 pub fn alloc() -> Option<Self> {
80 unsafe {
81 let ptr: *mut c_void = msg_send_0(class!(NSValue).as_ptr(), sel!(alloc));
82 Self::from_ptr(ptr)
83 }
84 }
85
86 #[inline]
90 pub fn init_with_bytes(&self, value: *const c_void, obj_c_type: *const c_char) -> Option<Self> {
91 unsafe {
92 let ptr: *mut c_void = msg_send_2(
93 self.as_ptr(),
94 sel!(initWithBytes:objCType:),
95 value,
96 obj_c_type,
97 );
98 Self::from_ptr(ptr)
99 }
100 }
101
102 #[inline]
106 pub fn init_with_coder(&self, coder: *const c_void) -> Option<Self> {
107 unsafe {
108 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithCoder:), coder);
109 Self::from_ptr(ptr)
110 }
111 }
112
113 #[inline]
117 pub fn get_value(&self, value: *mut c_void, size: UInteger) {
118 unsafe {
119 let _: () = msg_send_2(self.as_ptr(), sel!(getValue:size:), value, size);
120 }
121 }
122
123 #[inline]
127 pub fn objc_type(&self) -> *const c_char {
128 unsafe { msg_send_0(self.as_ptr(), sel!(objCType)) }
129 }
130
131 #[inline]
135 pub fn is_equal_to_value(&self, value: &Value) -> bool {
136 unsafe { msg_send_1(self.as_ptr(), sel!(isEqualToValue:), value.as_ptr()) }
137 }
138
139 #[inline]
143 pub fn pointer_value(&self) -> *mut c_void {
144 unsafe { msg_send_0(self.as_ptr(), sel!(pointerValue)) }
145 }
146
147 #[inline]
153 pub unsafe fn from_ptr(ptr: *mut c_void) -> Option<Self> {
154 NonNull::new(ptr).map(Self)
155 }
156}
157
158impl Referencing for Value {
159 #[inline]
160 fn as_ptr(&self) -> *const c_void {
161 self.0.as_ptr()
162 }
163}
164
165impl Copying for Value {
166 #[inline]
167 fn copy(&self) -> Option<Self> {
168 unsafe {
169 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
170 Self::from_ptr(ptr)
171 }
172 }
173}
174
175unsafe impl Send for Value {}
176unsafe impl Sync for Value {}
177
178#[repr(transparent)]
182#[derive(Clone)]
183pub struct Number(NonNull<c_void>);
184
185impl Number {
186 #[inline]
190 pub fn number_with_char(value: i8) -> Option<Self> {
191 unsafe {
192 let ptr: *mut c_void =
193 msg_send_1(class!(NSNumber).as_ptr(), sel!(numberWithChar:), value);
194 Self::from_ptr(ptr)
195 }
196 }
197
198 #[inline]
200 pub fn number_with_unsigned_char(value: u8) -> Option<Self> {
201 unsafe {
202 let ptr: *mut c_void = msg_send_1(
203 class!(NSNumber).as_ptr(),
204 sel!(numberWithUnsignedChar:),
205 value,
206 );
207 Self::from_ptr(ptr)
208 }
209 }
210
211 #[inline]
213 pub fn number_with_short(value: i16) -> Option<Self> {
214 unsafe {
215 let ptr: *mut c_void =
216 msg_send_1(class!(NSNumber).as_ptr(), sel!(numberWithShort:), value);
217 Self::from_ptr(ptr)
218 }
219 }
220
221 #[inline]
223 pub fn number_with_unsigned_short(value: u16) -> Option<Self> {
224 unsafe {
225 let ptr: *mut c_void = msg_send_1(
226 class!(NSNumber).as_ptr(),
227 sel!(numberWithUnsignedShort:),
228 value,
229 );
230 Self::from_ptr(ptr)
231 }
232 }
233
234 #[inline]
236 pub fn number_with_int(value: i32) -> Option<Self> {
237 unsafe {
238 let ptr: *mut c_void =
239 msg_send_1(class!(NSNumber).as_ptr(), sel!(numberWithInt:), value);
240 Self::from_ptr(ptr)
241 }
242 }
243
244 #[inline]
246 pub fn number_with_unsigned_int(value: u32) -> Option<Self> {
247 unsafe {
248 let ptr: *mut c_void = msg_send_1(
249 class!(NSNumber).as_ptr(),
250 sel!(numberWithUnsignedInt:),
251 value,
252 );
253 Self::from_ptr(ptr)
254 }
255 }
256
257 #[inline]
259 pub fn number_with_long(value: std::ffi::c_long) -> Option<Self> {
260 unsafe {
261 let ptr: *mut c_void =
262 msg_send_1(class!(NSNumber).as_ptr(), sel!(numberWithLong:), value);
263 Self::from_ptr(ptr)
264 }
265 }
266
267 #[inline]
269 pub fn number_with_unsigned_long(value: std::ffi::c_ulong) -> Option<Self> {
270 unsafe {
271 let ptr: *mut c_void = msg_send_1(
272 class!(NSNumber).as_ptr(),
273 sel!(numberWithUnsignedLong:),
274 value,
275 );
276 Self::from_ptr(ptr)
277 }
278 }
279
280 #[inline]
282 pub fn number_with_long_long(value: i64) -> Option<Self> {
283 unsafe {
284 let ptr: *mut c_void =
285 msg_send_1(class!(NSNumber).as_ptr(), sel!(numberWithLongLong:), value);
286 Self::from_ptr(ptr)
287 }
288 }
289
290 #[inline]
292 pub fn number_with_unsigned_long_long(value: u64) -> Option<Self> {
293 unsafe {
294 let ptr: *mut c_void = msg_send_1(
295 class!(NSNumber).as_ptr(),
296 sel!(numberWithUnsignedLongLong:),
297 value,
298 );
299 Self::from_ptr(ptr)
300 }
301 }
302
303 #[inline]
305 pub fn number_with_float(value: f32) -> Option<Self> {
306 unsafe {
307 let ptr: *mut c_void =
308 msg_send_1(class!(NSNumber).as_ptr(), sel!(numberWithFloat:), value);
309 Self::from_ptr(ptr)
310 }
311 }
312
313 #[inline]
315 pub fn number_with_double(value: f64) -> Option<Self> {
316 unsafe {
317 let ptr: *mut c_void =
318 msg_send_1(class!(NSNumber).as_ptr(), sel!(numberWithDouble:), value);
319 Self::from_ptr(ptr)
320 }
321 }
322
323 #[inline]
325 pub fn number_with_bool(value: bool) -> Option<Self> {
326 unsafe {
327 let ptr: *mut c_void =
328 msg_send_1(class!(NSNumber).as_ptr(), sel!(numberWithBool:), value);
329 Self::from_ptr(ptr)
330 }
331 }
332
333 #[inline]
335 pub fn alloc() -> Option<Self> {
336 unsafe {
337 let ptr: *mut c_void = msg_send_0(class!(NSNumber).as_ptr(), sel!(alloc));
338 Self::from_ptr(ptr)
339 }
340 }
341
342 #[inline]
346 pub fn init_with_coder(&self, coder: *const c_void) -> Option<Self> {
347 unsafe {
348 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithCoder:), coder);
349 Self::from_ptr(ptr)
350 }
351 }
352
353 #[inline]
355 pub fn init_with_char(&self, value: i8) -> Option<Self> {
356 unsafe {
357 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithChar:), value);
358 Self::from_ptr(ptr)
359 }
360 }
361
362 #[inline]
364 pub fn init_with_unsigned_char(&self, value: u8) -> Option<Self> {
365 unsafe {
366 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithUnsignedChar:), value);
367 Self::from_ptr(ptr)
368 }
369 }
370
371 #[inline]
373 pub fn init_with_short(&self, value: i16) -> Option<Self> {
374 unsafe {
375 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithShort:), value);
376 Self::from_ptr(ptr)
377 }
378 }
379
380 #[inline]
382 pub fn init_with_unsigned_short(&self, value: u16) -> Option<Self> {
383 unsafe {
384 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithUnsignedShort:), value);
385 Self::from_ptr(ptr)
386 }
387 }
388
389 #[inline]
391 pub fn init_with_int(&self, value: i32) -> Option<Self> {
392 unsafe {
393 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithInt:), value);
394 Self::from_ptr(ptr)
395 }
396 }
397
398 #[inline]
400 pub fn init_with_unsigned_int(&self, value: u32) -> Option<Self> {
401 unsafe {
402 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithUnsignedInt:), value);
403 Self::from_ptr(ptr)
404 }
405 }
406
407 #[inline]
409 pub fn init_with_long(&self, value: std::ffi::c_long) -> Option<Self> {
410 unsafe {
411 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithLong:), value);
412 Self::from_ptr(ptr)
413 }
414 }
415
416 #[inline]
418 pub fn init_with_unsigned_long(&self, value: std::ffi::c_ulong) -> Option<Self> {
419 unsafe {
420 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithUnsignedLong:), value);
421 Self::from_ptr(ptr)
422 }
423 }
424
425 #[inline]
427 pub fn init_with_long_long(&self, value: i64) -> Option<Self> {
428 unsafe {
429 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithLongLong:), value);
430 Self::from_ptr(ptr)
431 }
432 }
433
434 #[inline]
436 pub fn init_with_unsigned_long_long(&self, value: u64) -> Option<Self> {
437 unsafe {
438 let ptr: *mut c_void =
439 msg_send_1(self.as_ptr(), sel!(initWithUnsignedLongLong:), value);
440 Self::from_ptr(ptr)
441 }
442 }
443
444 #[inline]
446 pub fn init_with_float(&self, value: f32) -> Option<Self> {
447 unsafe {
448 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithFloat:), value);
449 Self::from_ptr(ptr)
450 }
451 }
452
453 #[inline]
455 pub fn init_with_double(&self, value: f64) -> Option<Self> {
456 unsafe {
457 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithDouble:), value);
458 Self::from_ptr(ptr)
459 }
460 }
461
462 #[inline]
464 pub fn init_with_bool(&self, value: bool) -> Option<Self> {
465 unsafe {
466 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithBool:), value);
467 Self::from_ptr(ptr)
468 }
469 }
470
471 #[inline]
475 pub fn char_value(&self) -> i8 {
476 unsafe { msg_send_0(self.as_ptr(), sel!(charValue)) }
477 }
478
479 #[inline]
481 pub fn unsigned_char_value(&self) -> u8 {
482 unsafe { msg_send_0(self.as_ptr(), sel!(unsignedCharValue)) }
483 }
484
485 #[inline]
487 pub fn short_value(&self) -> i16 {
488 unsafe { msg_send_0(self.as_ptr(), sel!(shortValue)) }
489 }
490
491 #[inline]
493 pub fn unsigned_short_value(&self) -> u16 {
494 unsafe { msg_send_0(self.as_ptr(), sel!(unsignedShortValue)) }
495 }
496
497 #[inline]
499 pub fn int_value(&self) -> i32 {
500 unsafe { msg_send_0(self.as_ptr(), sel!(intValue)) }
501 }
502
503 #[inline]
505 pub fn unsigned_int_value(&self) -> u32 {
506 unsafe { msg_send_0(self.as_ptr(), sel!(unsignedIntValue)) }
507 }
508
509 #[inline]
511 pub fn long_value(&self) -> std::ffi::c_long {
512 unsafe { msg_send_0(self.as_ptr(), sel!(longValue)) }
513 }
514
515 #[inline]
517 pub fn unsigned_long_value(&self) -> std::ffi::c_ulong {
518 unsafe { msg_send_0(self.as_ptr(), sel!(unsignedLongValue)) }
519 }
520
521 #[inline]
523 pub fn long_long_value(&self) -> i64 {
524 unsafe { msg_send_0(self.as_ptr(), sel!(longLongValue)) }
525 }
526
527 #[inline]
529 pub fn unsigned_long_long_value(&self) -> u64 {
530 unsafe { msg_send_0(self.as_ptr(), sel!(unsignedLongLongValue)) }
531 }
532
533 #[inline]
535 pub fn float_value(&self) -> f32 {
536 unsafe { msg_send_0(self.as_ptr(), sel!(floatValue)) }
537 }
538
539 #[inline]
541 pub fn double_value(&self) -> f64 {
542 unsafe { msg_send_0(self.as_ptr(), sel!(doubleValue)) }
543 }
544
545 #[inline]
547 pub fn bool_value(&self) -> bool {
548 unsafe { msg_send_0(self.as_ptr(), sel!(boolValue)) }
549 }
550
551 #[inline]
553 pub fn integer_value(&self) -> Integer {
554 unsafe { msg_send_0(self.as_ptr(), sel!(integerValue)) }
555 }
556
557 #[inline]
559 pub fn unsigned_integer_value(&self) -> UInteger {
560 unsafe { msg_send_0(self.as_ptr(), sel!(unsignedIntegerValue)) }
561 }
562
563 #[inline]
565 pub fn string_value(&self) -> *mut String {
566 unsafe { msg_send_0(self.as_ptr(), sel!(stringValue)) }
567 }
568
569 #[inline]
571 pub fn compare(&self, other: &Number) -> ComparisonResult {
572 unsafe { msg_send_1(self.as_ptr(), sel!(compare:), other.as_ptr()) }
573 }
574
575 #[inline]
577 pub fn is_equal_to_number(&self, number: &Number) -> bool {
578 unsafe { msg_send_1(self.as_ptr(), sel!(isEqualToNumber:), number.as_ptr()) }
579 }
580
581 #[inline]
583 pub fn description_with_locale(&self, locale: *const c_void) -> *mut String {
584 unsafe { msg_send_1(self.as_ptr(), sel!(descriptionWithLocale:), locale) }
585 }
586
587 #[inline]
593 pub unsafe fn from_ptr(ptr: *mut c_void) -> Option<Self> {
594 NonNull::new(ptr).map(Self)
595 }
596}
597
598impl Referencing for Number {
599 #[inline]
600 fn as_ptr(&self) -> *const c_void {
601 self.0.as_ptr()
602 }
603}
604
605impl Copying for Number {
606 #[inline]
607 fn copy(&self) -> Option<Self> {
608 unsafe {
609 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
610 Self::from_ptr(ptr)
611 }
612 }
613}
614
615unsafe impl Send for Number {}
616unsafe impl Sync for Number {}
617
618impl std::fmt::Debug for Number {
619 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
620 f.debug_struct("Number").field("ptr", &self.0).finish()
621 }
622}
623
624#[cfg(test)]
625mod tests {
626 use super::*;
627
628 #[test]
629 fn test_number_size() {
630 assert_eq!(
631 std::mem::size_of::<Number>(),
632 std::mem::size_of::<*mut c_void>()
633 );
634 }
635
636 #[test]
637 fn test_value_size() {
638 assert_eq!(
639 std::mem::size_of::<Value>(),
640 std::mem::size_of::<*mut c_void>()
641 );
642 }
643}