use std::ptr::NonNull;
#[derive(Debug)]
pub struct Raw<T: IsA<sys::signal_type_base>>(NonNull<T>);
impl<T: IsA<sys::signal_type_base>> Raw<T> {
pub unsafe fn from_ptr(raw: *mut T) -> Raw<T> {
debug_assert!(!raw.is_null());
Raw(NonNull::new_unchecked(raw))
}
pub unsafe fn copied_from(raw: *mut T) -> Raw<T> {
sys::signal_type_ref(T::upcast(raw));
Raw::from_ptr(raw)
}
pub fn upcast<Parent>(self) -> Raw<Parent>
where
T: IsA<Parent>,
Parent: IsA<sys::signal_type_base>,
{
unsafe { Raw::from_ptr(T::upcast(self.into_inner())) }
}
pub fn as_ptr(&self) -> *mut T { self.0.as_ptr() }
pub fn into_inner(self) -> *mut T {
let ptr = self.0.as_ptr();
std::mem::forget(self);
ptr
}
pub fn as_const_ptr(&self) -> *const T { self.as_ptr() as *const T }
}
impl<T: IsA<sys::signal_type_base>> Clone for Raw<T> {
fn clone(&self) -> Raw<T> { unsafe { Raw::copied_from(self.as_ptr()) } }
}
impl<T: IsA<sys::signal_type_base>> Drop for Raw<T> {
fn drop(&mut self) {
unsafe {
sys::signal_type_unref(T::upcast(self.0.as_ptr()));
}
}
}
pub unsafe trait IsA<Parent> {
unsafe fn upcast(this: *mut Self) -> *mut Parent;
}
impl_is_a! {
sys::ciphertext_message => sys::signal_type_base,
sys::ec_key_pair => sys::signal_type_base,
sys::ec_private_key => sys::signal_type_base,
sys::ec_public_key => sys::signal_type_base,
sys::hkdf_context => sys::signal_type_base,
sys::pre_key_signal_message => sys::signal_type_base,
sys::ratchet_identity_key_pair => sys::signal_type_base,
sys::session_pre_key => sys::signal_type_base,
sys::session_pre_key_bundle => sys::signal_type_base,
sys::session_record => sys::signal_type_base,
sys::session_signed_pre_key => sys::signal_type_base,
sys::session_state => sys::signal_type_base,
sys::signal_message => sys::signal_type_base,
}