macro_rules! impl_wrapper {
($Name:ident: $T:ty) => {
#[inline]
pub unsafe fn from_raw(raw: $T) -> Self {
$Name(NonNull::<$T>::new(raw).unwrap())
}
#[inline]
pub fn as_raw(&self) -> $T {
self.0.as_ptr()
}
#[inline]
pub fn into_raw(self) -> $T {
let raw = self.as_raw();
::std::mem::forget(self);
raw
}
};
}
macro_rules! ffi_enum_wrapper {
($(#[$Attr:meta])* pub enum $Name:ident: $T:ty {
$($(#[$ItemAttr:meta])* $Item:ident = $Value:expr),+
}) => {
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
$(#[$Attr])*
pub enum $Name {
$($(#[$ItemAttr])* $Item,)+
Other($T),
}
impl $Name {
#[inline]
pub unsafe fn from_raw(raw: $T) -> $Name {
$(if raw == ($Value as $T) {
$Name::$Item
} else )+ {
$Name::Other(raw)
}
}
#[inline]
pub fn raw(&self) -> $T {
match *self {
$($Name::$Item => $Value as $T,)+
$Name::Other(other) => other,
}
}
}
impl ::std::fmt::Debug for $Name {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match *self {
$($Name::$Item => {
write!(f, concat!(stringify!($Name), "::",
stringify!($Item), "({:?})"), self.raw())
})+
_ => write!(f, concat!(stringify!($Name), "({:?})"), self.raw()),
}
}
}
};
($(#[$Attr:meta])* pub enum $Name:ident: $T:ty {
$($(#[$ItemAttr:meta])* $Item:ident = $Value:expr,)+
}) => {
ffi_enum_wrapper! {
$(#[$Attr])*
pub enum $Name: $T {
$($(#[$ItemAttr])* $Item = $Value),+
}
}
};
}
pub(crate) trait Ptr {
type Inner;
}
impl<T> Ptr for *mut T {
type Inner = T;
}
impl<T> Ptr for *const T {
type Inner = T;
}