mod static_data; type OwnedPtr = *mut T; type BorrowedPtr = *const T; macro_rules! ffi_getter { ( $type:ty, $func:ident, $returns: ty ) => { paste::paste! { #[no_mangle] extern "C" fn [< $type:snake _ $func >](ptr: ExternPointer<$type>) -> $returns { ptr.as_ref().$func() } } }; } macro_rules! ffi_arc_getter { ( $type:ty, $func:ident, $returns: ty ) => { paste::paste! { #[no_mangle] extern "C" fn [< $type:snake _ $func >](ptr: ExternPointer>) -> $returns { ptr.as_ref().$func() } } }; } macro_rules! ffi_arc_stringkey_getter { ( $type:ty, $func:ident ) => { paste::paste! { #[no_mangle] extern "C" fn [< $type:lower _ $func >](ptr: ExternPointer>) -> OwnedPtr { std::ffi::CString::new(ptr.as_ref().$func().str()).unwrap().into_raw() } } }; } macro_rules! ffi_vec_value_getters { ( $type:ty, $func:ident, $returns: ty ) => { paste::paste! { #[no_mangle] extern "C" fn [< $type:lower _ $func _length>](ptr: ExternPointer>) -> usize { ptr.as_ref().$func().len() } #[no_mangle] extern "C" fn [< $type:lower _ $func _get>](ptr: ExternPointer>, index: usize) -> $returns { *ptr.as_ref().$func().get(index).unwrap() } } }; } macro_rules! ffi_vec_stringkey_getters { ( $type:ident, $func:ident ) => { paste::paste! { #[no_mangle] extern "C" fn [< $type:lower _ $func _length>](ptr: ExternPointer>) -> usize { ptr.as_ref().$func().len() } #[no_mangle] extern "C" fn [< $type:lower _ $func _get>](ptr: ExternPointer>, index: usize) -> OwnedPtr { CString::new(ptr.as_ref().$func().get(index).unwrap().str()).unwrap().into_raw() } } }; } use crate::{ValueIdentifiable, ValueIdentifier}; pub(self) use ffi_arc_getter; pub(self) use ffi_arc_stringkey_getter; pub(self) use ffi_getter; pub(self) use ffi_vec_stringkey_getters; pub(self) use ffi_vec_value_getters; use std::sync::Arc; #[repr(C)] pub(self) struct ExternPointer { ptr: *mut T, } impl ExternPointer { pub(self) fn as_ref(&self) -> &T { unsafe { self.ptr.as_ref().expect(&format!( "Given pointer of type '{}' was null", std::any::type_name::() )) } } pub(self) fn as_mut(&self) -> &mut T { unsafe { self.ptr.as_mut().expect(&format!( "Given pointer of type '{}' was null", std::any::type_name::() )) } } } impl Into> for *mut T { fn into(self) -> ExternPointer { ExternPointer { ptr: self } } } #[repr(C)] pub(self) struct IdentifiablePointer { pub ptr: *const T, pub id: ValueIdentifier, } impl From> for IdentifiablePointer> { fn from(v: Arc) -> Self { let id = v.value_identifier(); Self { ptr: Box::into_raw(Box::new(v)), id, } } } impl From> for IdentifiablePointer { fn from(v: Box) -> Self { let id = v.value_identifier(); Self { ptr: Box::into_raw(v), id, } } } impl From<*const T> for IdentifiablePointer { fn from(v: *const T) -> Self { let id = unsafe { v.as_ref() }.unwrap().value_identifier(); Self { ptr: v, id } } } impl IdentifiablePointer { pub fn none() -> Self { Self { ptr: std::ptr::null(), id: Default::default(), } } }