tesseract_swift_utils/ptr/
any.rs

1use 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}