use std::cell::UnsafeCell;
use std::marker::PhantomPinned;
#[repr(transparent)]
pub struct PhantomOpaque {
pinned: PhantomPinned,
unfreeze: UnsafeCell<()>,
}
pub unsafe trait Opaque: Sized {
type Inner;
unsafe fn try_from_raw<'r>(ptr: *mut Self::Inner) -> Option<&'r Self> {
unsafe { Some(Self::from_raw(ptr)) }
}
unsafe fn from_raw<'r>(ptr: *mut Self::Inner) -> &'r Self {
debug_assert!(!ptr.is_null());
unsafe { &*(ptr as *const Self) }
}
unsafe fn from_ptr<'r>(ptr: *mut Self::Inner) -> Option<&'r Self> {
if ptr.is_null() {
None
} else {
unsafe { Some(Self::from_raw(ptr)) }
}
}
fn as_raw(&self) -> *mut Self::Inner {
self as *const Self as *mut Self::Inner
}
unsafe fn cast_unchecked<T: Opaque<Inner = Self::Inner>>(&self) -> &T {
T::from_raw(self.as_raw())
}
fn cast<T: Opaque<Inner = Self::Inner>>(&self) -> &T {
Self::try_cast(self).unwrap()
}
fn try_cast<T: Opaque<Inner = Self::Inner>>(&self) -> Option<&T> {
unsafe { T::try_from_raw(self.as_raw()) }
}
}