1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
use std::error::Error;
use std::marker::PhantomData;
use std::sync::Arc;

use super::null_ptr_error;
use super::{FromForeign, InputType};

pub struct ArcRefMarshaler<T>(PhantomData<T>);

impl<T> InputType for ArcRefMarshaler<T> {
    type Foreign = *const T;
}

impl<'a, T> FromForeign<*const T, Arc<T>> for ArcRefMarshaler<T> {
    type Error = Box<dyn Error>;

    #[inline(always)]
    unsafe fn from_foreign(foreign: *const T) -> Result<Arc<T>, Self::Error> {
        if foreign.is_null() {
            return Err(null_ptr_error());
        }

        let arc = Arc::from_raw(foreign);
        let cloned = Arc::clone(&arc);
        let _x = Arc::into_raw(arc);

        Ok(cloned)
    }
}

// impl<'a, T> FromForeign<*const T, &'a mut Arc<T>> for ArcRefMarshaler<T> {
//     type Error = Box<dyn Error>;

//     #[inline(always)]
//     unsafe fn from_foreign(foreign: *const T) -> Result<&'a mut T, Self::Error> {
//         log::debug!(
//             "<ArcMarshaler<{ty}> as FromForeign<*const T, &'a mut T>>::from_foreign({:?})",
//             foreign,
//             ty = std::any::type_name::<T>()
//         );

//         if foreign.is_null_mut() {
//             return Err(null_ptr_error());
//         }

//         let ptr = unsafe { transmute::<*const T, *mut T>(foreign) };

//         Ok(unsafe { &mut *ptr as &'a mut T })
//     }
// }