use super::*;
#[doc(hidden)]
pub unsafe trait Abi: Sized {
type Abi;
fn abi(&self) -> Self::Abi {
unsafe { core::mem::transmute_copy(self) }
}
unsafe fn from_abi(abi: Self::Abi) -> Result<Self> {
if Self::abi_is_possibly_valid(&abi) {
Ok(core::mem::transmute_copy(&abi))
} else {
Err(Error::OK)
}
}
unsafe fn from_abi_ref(abi: &Self::Abi) -> Result<&Self> {
if Self::abi_is_possibly_valid(abi) {
Ok(core::mem::transmute(abi))
} else {
Err(Error::OK)
}
}
fn abi_is_possibly_valid(abi: &Self::Abi) -> bool {
true
}
}
unsafe impl<T: Interface> Abi for Option<T> {
type Abi = *mut core::ffi::c_void;
}
unsafe impl<T: Interface> Abi for T {
type Abi = *mut core::ffi::c_void;
fn abi_is_possibly_valid(abi: &Self::Abi) -> bool {
!abi.is_null()
}
}
unsafe impl<T> Abi for *mut T {
type Abi = Self;
}
unsafe impl<T> Abi for *const T {
type Abi = Self;
}
macro_rules! primitive_types {
($($t:ty),+) => {
$(
unsafe impl Abi for $t {
type Abi = Self;
}
)*
};
}
primitive_types! {
bool,
i8,
u8,
i16,
u16,
i32,
u32,
i64,
u64,
f32,
f64,
usize,
isize
}