tesseract_swift_utils/ptr/
any.rs1use super::SyncPtr;
2use crate::error::CError;
3use crate::result::Result;
4use crate::Void;
5use std::any::Any;
6use std::mem::ManuallyDrop;
7
8#[repr(C)]
9pub struct CAnyRustPtr(SyncPtr<Void>);
10
11impl CAnyRustPtr {
12 pub fn new<T: Any>(val: T) -> Self {
13 let bx: Box<dyn Any> = Box::new(val);
14 bx.into()
15 }
16
17 pub fn raw(ptr: SyncPtr<Void>) -> Self {
18 Self(ptr)
19 }
20
21 pub fn as_ref<T: Any>(&self) -> Result<&T> {
22 unsafe { self.0.as_typed_ref::<Box<dyn Any>>() }
23 .ok_or_else(|| CError::null::<Self>())
24 .and_then(|any| {
25 any.downcast_ref::<T>().ok_or_else(|| CError::cast::<Self, T>())
26 })
27 }
28
29 pub fn as_mut<T: Any>(&mut self) -> Result<&mut T> {
30 unsafe { self.0.as_typed_mut::<Box<dyn Any>>() }
31 .ok_or_else(|| CError::null::<Self>())
32 .and_then(|any| {
33 any.downcast_mut::<T>().ok_or_else(|| CError::cast::<Self, T>())
34 })
35 }
36
37 pub fn take<T: Any>(mut self) -> Result<T> {
38 if self.0.is_null() {
39 return Err(CError::null::<Self>());
40 }
41 let val = unsafe { self.0.take_typed::<Box<dyn Any>>() };
42 std::mem::forget(self);
43 val.downcast::<T>()
44 .map_err(|_| CError::cast::<Self, T>())
45 .map(|boxed| *boxed)
46 }
47}
48
49impl Drop for CAnyRustPtr {
50 fn drop(&mut self) {
51 let _ = unsafe { self.0.take_typed::<Box<dyn Any>>() };
52 }
53}
54
55impl From<CAnyRustPtr> for usize {
56 fn from(ptr: CAnyRustPtr) -> Self {
57 ptr.0.ptr() as usize
58 }
59}
60
61impl From<usize> for CAnyRustPtr {
62 fn from(ptr: usize) -> Self {
63 Self::raw(SyncPtr::raw(ptr as *mut Void))
64 }
65}
66
67impl From<Box<dyn Any>> for CAnyRustPtr {
68 fn from(boxed: Box<dyn Any>) -> Self {
69 Self::raw(SyncPtr::new(boxed).as_void())
70 }
71}
72
73pub trait IntoAnyPtr: Any + Sized {
74 fn into_any_ptr(self) -> CAnyRustPtr {
75 CAnyRustPtr::new(self)
76 }
77}
78
79impl<T: IntoAnyPtr> From<T> for CAnyRustPtr {
80 fn from(val: T) -> Self {
81 val.into_any_ptr()
82 }
83}
84
85impl<T: IntoAnyPtr> IntoAnyPtr for Option<T> {
86 fn into_any_ptr(self) -> CAnyRustPtr {
87 match self {
88 Some(val) => val.into_any_ptr(),
89 None => CAnyRustPtr::raw(SyncPtr::null()),
90 }
91 }
92}
93
94#[no_mangle]
95pub unsafe extern "C" fn tesseract_utils_any_rust_ptr_free(ptr: &mut ManuallyDrop<CAnyRustPtr>) {
96 let _ = ManuallyDrop::take(ptr);
97}