use std::{fmt, sync::Arc};
#[derive(Clone, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct Handle(u64);
impl Handle {
pub fn from_pointer<T>(ptr: *const T) -> Self {
Self(ptr as u64)
}
pub fn as_pointer<T>(&self) -> *const T {
self.0 as *const T
}
pub fn is_foreign(&self) -> bool {
(self.0 & 1) == 1
}
pub unsafe fn from_raw(raw: u64) -> Option<Self> {
if raw == 0 {
None
} else {
Some(Self(raw))
}
}
pub fn from_raw_unchecked(raw: u64) -> Self {
Self(raw)
}
pub fn as_raw(&self) -> u64 {
self.0
}
pub fn from_arc<T>(arc: Arc<T>) -> Self {
Self::from_pointer(Arc::into_raw(arc))
}
pub unsafe fn into_arc<T>(self) -> Arc<T> {
Arc::from_raw(self.as_pointer())
}
pub unsafe fn into_arc_borrowed<T>(self) -> Arc<T> {
self.clone_arc_handle::<T>();
Arc::from_raw(self.as_pointer())
}
pub unsafe fn clone_arc_handle<T>(&self) -> Self {
Arc::increment_strong_count(self.as_pointer::<T>());
Self(self.0)
}
}
impl fmt::Debug for Handle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Handle(0x{:x})", self.0)
}
}