PkmnLib_rs/src/ffi/mod.rs

101 lines
2.6 KiB
Rust

mod static_data;
type OwnedPtr<T> = *mut T;
type BorrowedPtr<T> = *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<c_char> {
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<c_char> {
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<T: ?Sized> {
ptr: *mut T,
}
impl<T: ?Sized> ExternPointer<T> {
pub(self) fn as_ref(&self) -> &T {
unsafe {
self.ptr.as_ref().expect(&format!(
"Given pointer of type '{}' was null",
std::any::type_name::<T>()
))
}
}
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::<T>()
))
}
}
}
impl<T> Into<ExternPointer<T>> for *mut T {
fn into(self) -> ExternPointer<T> {
ExternPointer { ptr: self }
}
}