Skip to main content

shared/
shadow_type.rs

1#[macro_export]
2macro_rules! generate_shadow_type {
3    ($proxy_name:ident, $real_type:ty) => {
4        /// Opaque shadow type generated for FFI pointer boundaries.
5        #[repr(C)]
6        pub struct $proxy_name {
7            _private: [u8; 0], // Zero-sized type to prevent C instantiation but safe for raw pointers
8        }
9
10        impl $proxy_name {
11            /// Converts a real allocated instance into an opaque raw pointer handle.
12            ///
13            /// Note: This moves the real object onto the heap via Box to ensure its
14            /// memory remains valid after this function returns.
15            pub const fn from_real(real: &mut $real_type) -> *mut Self {
16                real as *mut $real_type as *mut Self
17            }
18
19            /// Consumes the opaque raw pointer handle and returns the original real type,
20            /// reclaiming ownership and freeing the underlying heap allocation.
21            ///
22            /// # Safety
23            /// The pointer must be non-null and must have been created by `from_real`.
24            #[inline]
25            pub unsafe fn into_real(ptr: *mut Self) -> *mut $real_type {
26                ptr as *mut $real_type
27            }
28
29            /// Temporarily borrows the real type immutably from the opaque pointer.
30            ///
31            /// # Safety
32            /// The pointer must be valid and dereferenceable for the duration of life 'a.
33            #[inline]
34            pub unsafe fn as_real<'a>(ptr: *const Self) -> &'a $real_type {
35                unsafe { &*(ptr as *const $real_type) }
36            }
37
38            /// Temporarily borrows the real type mutably from the opaque pointer.
39            ///
40            /// # Safety
41            /// The pointer must be valid, dereferenceable, and unaliased for the duration of life 'a.
42            #[inline]
43            pub unsafe fn as_real_mut<'a>(ptr: *mut Self) -> &'a mut $real_type {
44                unsafe { &mut *(ptr as *mut $real_type) }
45            }
46        }
47
48        impl core::ops::Deref for $proxy_name {
49            type Target = $real_type;
50
51            #[inline]
52            fn deref(&self) -> &Self::Target {
53                unsafe { Self::as_real(self as *const Self) }
54            }
55        }
56
57        impl core::ops::DerefMut for $proxy_name {
58            #[inline]
59            fn deref_mut(&mut self) -> &mut Self::Target {
60                unsafe { Self::as_real_mut(self as *mut Self) }
61            }
62        }
63
64        impl AsRef<$real_type> for $proxy_name {
65            #[inline]
66            fn as_ref(&self) -> &$real_type {
67                unsafe { Self::as_real(self as *const Self) }
68            }
69        }
70
71        impl AsMut<$real_type> for $proxy_name {
72            #[inline]
73            fn as_mut(&mut self) -> &mut $real_type {
74                unsafe { Self::as_real_mut(self as *mut Self) }
75            }
76        }
77    };
78}