pub unsafe trait AbiTransferable: Sized {
type Abi;
fn get_abi(&self) -> Self::Abi;
fn set_abi(&mut self) -> *mut Self::Abi;
fn from_abi(abi: &Self::Abi) -> &Self {
unsafe { std::mem::transmute_copy(&abi) }
}
fn from_mut_abi(abi: &mut Self::Abi) -> &mut Self {
unsafe { std::mem::transmute_copy(&abi) }
}
unsafe fn slice_from_abi<'a>(abi: *const Self::Abi, len: usize) -> &'a [Self] {
std::slice::from_raw_parts(std::mem::transmute_copy(&abi), len)
}
unsafe fn slice_from_mut_abi<'a>(abi: *mut Self::Abi, len: usize) -> &'a mut [Self] {
std::slice::from_raw_parts_mut(std::mem::transmute_copy(&abi), len)
}
fn into_abi(self) -> Self::Abi {
let abi = unsafe { std::mem::transmute_copy(&self) };
std::mem::forget(self);
abi
}
}
macro_rules! primitive_transferable_type {
($($t:ty),+) => {
$(unsafe impl AbiTransferable for $t {
type Abi = Self;
fn get_abi(&self) -> Self::Abi {
*self
}
fn set_abi(&mut self) -> *mut Self::Abi {
self as *mut Self::Abi
}
})*
};
}
primitive_transferable_type! {
bool,
i8,
u8,
i16,
u16,
i32,
u32,
i64,
u64,
f32,
f64,
crate::sys::GUID
}
unsafe impl<T> AbiTransferable for *mut T {
type Abi = Self;
fn get_abi(&self) -> Self::Abi {
*self
}
fn set_abi(&mut self) -> *mut Self::Abi {
self as *mut Self::Abi
}
}
unsafe impl<T> AbiTransferable for *const T {
type Abi = Self;
fn get_abi(&self) -> Self::Abi {
*self
}
fn set_abi(&mut self) -> *mut Self::Abi {
self as *mut Self::Abi
}
}
unsafe impl<T: crate::Interface> AbiTransferable for T {
type Abi = std::ptr::NonNull<std::ptr::NonNull<<T as crate::Interface>::VTable>>;
fn get_abi(&self) -> Self::Abi {
self.as_raw()
}
fn set_abi(&mut self) -> *mut Self::Abi {
&mut self.as_raw()
}
}
unsafe impl<T: crate::Interface> AbiTransferable for Option<T> {
type Abi = *mut std::ptr::NonNull<<T as crate::Interface>::VTable>;
fn get_abi(&self) -> Self::Abi {
self.as_ref()
.map(|p| p.as_raw().as_ptr())
.unwrap_or(::std::ptr::null_mut())
}
fn set_abi(&mut self) -> *mut Self::Abi {
&mut self
.as_mut()
.map(|p| p.as_raw().as_ptr())
.unwrap_or(::std::ptr::null_mut())
}
}