tesseract_swift_utils/ptr/
drop.rs

1use super::SyncPtr;
2use crate::error::CError;
3use crate::result::Result;
4use crate::Void;
5use std::any::Any;
6
7#[repr(C)]
8pub struct CAnyDropPtr {
9    ptr: SyncPtr<Void>,
10    drop: extern "C" fn(&mut CAnyDropPtr),
11}
12
13impl Drop for CAnyDropPtr {
14    fn drop(&mut self) {
15        (self.drop)(self);
16    }
17}
18
19impl CAnyDropPtr {
20    pub fn new<T: Any>(val: T) -> Self {
21        let bx: Box<dyn Any> = Box::new(val);
22        bx.into()
23    }
24
25    pub fn raw(ptr: SyncPtr<Void>, drop: extern "C" fn(&mut CAnyDropPtr)) -> Self {
26        Self { ptr, drop }
27    }
28
29    pub fn as_ref<T: Any>(&self) -> Result<&T> {
30        unsafe { self.ptr.as_typed_ref::<Box<dyn Any>>() }
31            .ok_or_else(|| CError::null::<Self>())
32            .and_then(|any| {
33                any.downcast_ref::<T>().ok_or_else(|| CError::cast::<Self, T>())
34            })
35    }
36
37    pub fn as_mut<T: Any>(&mut self) -> Result<&mut T> {
38        unsafe { self.ptr.as_typed_mut::<Box<dyn Any>>() }
39            .ok_or_else(|| CError::null::<Self>())
40            .and_then(|any| {
41                any.downcast_mut::<T>().ok_or_else(|| CError::cast::<Self, T>())
42            })
43    }
44
45    pub fn take<T: Any>(mut self) -> Result<T> {
46        if self.ptr.is_null() {
47            return Err(CError::null::<Self>());
48        }
49        let val = unsafe { self.ptr.take_typed::<Box<dyn Any>>() };
50        std::mem::forget(self);
51        val.downcast::<T>()
52            .map_err(|_| CError::cast::<Self, T>())
53            .map(|boxed| *boxed)
54    }
55
56    pub fn ptr(&self) -> &SyncPtr<Void> {
57        &self.ptr
58    }
59
60    pub fn is_null(&self) -> bool {
61        self.ptr.is_null()
62    }
63
64    extern "C" fn drop_value(ptr: &mut CAnyDropPtr) {
65        let _ = unsafe { ptr.ptr.take_typed::<Box<dyn Any>>() };
66    }
67}
68
69impl From<Box<dyn Any>> for CAnyDropPtr {
70    fn from(boxed: Box<dyn Any>) -> Self {
71        Self::raw(SyncPtr::new(boxed).as_void(), Self::drop_value)
72    }
73}