xlang_abi 0.2.0

ABI safe interfaces used by xlang
Documentation
use std::{marker::PhantomData, ptr::NonNull};

#[repr(transparent)]
pub(crate) struct Unique<T: ?Sized> {
    ptr: NonNull<T>,
    phantom: PhantomData<T>,
}

impl<T: ?Sized> core::fmt::Debug for Unique<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Unique").field("ptr", &self.ptr).finish()
    }
}

impl<T: ?Sized> core::hash::Hash for Unique<T> {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        self.ptr.hash(state);
    }
}

impl<T: ?Sized> core::cmp::PartialEq for Unique<T> {
    fn eq(&self, other: &Self) -> bool {
        self.ptr == other.ptr
    }
}

impl<T: ?Sized> core::cmp::Eq for Unique<T> {}

unsafe impl<T: Send> Send for Unique<T> {}
unsafe impl<T: Sync> Sync for Unique<T> {}
impl<T> Unpin for Unique<T> {}

impl<T> Unique<T> {
    #[must_use]
    pub const fn dangling() -> Self {
        Self {
            ptr: NonNull::dangling(),
            phantom: PhantomData,
        }
    }
}

impl<T: ?Sized> Unique<T> {
    pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
        Self {
            ptr: NonNull::new_unchecked(ptr),
            phantom: PhantomData,
        }
    }

    pub const unsafe fn new_nonnull_unchecked(ptr: NonNull<T>) -> Self {
        Self {
            ptr,
            phantom: PhantomData,
        }
    }

    pub unsafe fn as_ref(&self) -> &T {
        self.ptr.as_ref()
    }

    pub unsafe fn as_mut(&mut self) -> &mut T {
        self.ptr.as_mut()
    }

    pub const fn as_ptr(&self) -> *mut T {
        self.ptr.as_ptr()
    }

    pub const fn as_nonnull(&self) -> NonNull<T> {
        self.ptr
    }
}