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_stringkey_getter { ( $type:ty, $func:ident ) => { paste::paste! { #[no_mangle] extern "C" fn [< $type:lower _ $func >](ptr: ExternPointer<$type>) -> 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<$type>) -> usize { ptr.as_ref().$func().len() } #[no_mangle] extern "C" fn [< $type:lower _ $func _get>](ptr: ExternPointer<$type>, 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<$type>) -> usize { ptr.as_ref().$func().len() } #[no_mangle] extern "C" fn [< $type:lower _ $func _get>](ptr: ExternPointer<$type>, index: usize) -> OwnedPtr { CString::new(ptr.as_ref().$func().get(index).unwrap().str()).unwrap().into_raw() } } }; } pub(self) use ffi_getter; pub(self) use ffi_stringkey_getter; pub(self) use ffi_vec_stringkey_getters; pub(self) use ffi_vec_value_getters; #[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 } } }