ffi_types 0.0.21

C ABI compatible wrappers for cbindgen/bindgen.
Documentation
/// Rust wrapper for &[T].
#[derive(Debug)]
#[repr(transparent)]
pub struct SliceRef<T: 'static>(pub(crate) SliceInner<T>);
static_assertions::assert_eq_size!(SliceRef<u8>, &[u8]);

/// Rust wrapper for &[u8].
/// Though this alias is not very useful in Rust side, it gives a simple aliased buffer type for cbindgen.
pub type ByteSliceRef = SliceRef<u8>;

/// Rust wrapper for Box<[u8]>
/// Though this alias is not very useful in Rust side, it gives a simple aliased buffer type for cbindgen.
pub type BoxedByteSlice = BoxedSlice<u8>;

/// Rust wrapper for &mut [u8].
#[derive(Debug)]
#[repr(transparent)]
pub struct MutSliceRef<T: 'static>(SliceInner<T>);
static_assertions::assert_eq_size!(MutSliceRef<u8>, &[u8]);

/// Rust wrapper for Box<[T]>.
///
/// Since boxed types are only created from Rust side, the value is expected to be valid under safe operations.
#[derive(Debug)]
#[repr(transparent)]
pub struct BoxedSlice<T: 'static>(pub(crate) SliceInner<T>);
static_assertions::assert_eq_size!(BoxedSlice<u8>, alloc::boxed::Box<[u8]>);

impl<T> Clone for SliceRef<T> {
    #[inline(always)]
    fn clone(&self) -> Self {
        *self
    }
}

impl<T> Copy for SliceRef<T> {}

impl<T> SliceRef<T> {
    /// Create a new wrapper for a static slice `&'static [T]`.
    /// See [`SliceRef::new_unbound`] to remove lifetime bound.
    #[inline(always)]
    pub const fn new(slice: &'static [T]) -> Self {
        Self(SliceInner::from_slice(slice))
    }

    /// Create a new wrapper for a slice `&[T]`.
    /// `unbound` means bounded lifetime will be removed to be static.
    ///
    /// # Safety
    /// The returned object must not outlive the given slice.
    #[inline(always)]
    pub unsafe fn new_unbound(slice: &'_ [T]) -> Self {
        Self::new(unsafe { crate::into_static(slice) })
    }

    /// Inverse of [`SliceRef::new`].
    #[inline(always)]
    pub fn into_slice(self) -> &'static [T] {
        let union = SliceUnion { inner: self.0 };
        unsafe { union.slice }
    }
}

impl<T> From<&'static [T]> for SliceRef<T> {
    #[inline(always)]
    fn from(slice: &'static [T]) -> Self {
        Self::new(slice)
    }
}

impl<T> From<SliceRef<T>> for &'static [T] {
    #[inline(always)]
    fn from(slice: SliceRef<T>) -> Self {
        slice.into_slice()
    }
}

impl<T> core::convert::AsRef<[T]> for SliceRef<T> {
    #[inline(always)]
    fn as_ref(&self) -> &[T] {
        self.into_slice()
    }
}

impl<T> core::borrow::Borrow<[T]> for SliceRef<T> {
    #[inline(always)]
    fn borrow(&self) -> &[T] {
        self.as_ref()
    }
}

impl<T> core::ops::Deref for SliceRef<T> {
    type Target = [T];

    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        self.as_ref()
    }
}

impl<T> MutSliceRef<T> {
    /// Create a new wrapper for a static slice `&'static mut [T]`.
    /// See [`MutSliceRef::new_unbound`] to remove lifetime bound.
    #[inline(always)]
    pub fn new(slice: &'static mut [T]) -> Self {
        Self(SliceInner::from_slice(slice))
    }

    /// Create a new wrapper for a slice `&mut [T]`.
    /// `unbound` means bounded lifetime will be removed to be static.
    ///
    /// # Safety
    /// The returned object must not outlive the given slice.
    #[inline(always)]
    pub unsafe fn new_unbound(slice: &'_ mut [T]) -> Self {
        Self::new(unsafe { crate::into_static_mut(slice) })
    }

    /// Inverse of [`MutSliceRef::new`].
    #[inline(always)]
    pub fn into_mut_slice(self) -> &'static mut [T] {
        let union = SliceUnion { inner: self.0 };
        unsafe { union.mut_slice }
    }
}

impl<T> From<&'static mut [T]> for MutSliceRef<T> {
    #[inline(always)]
    fn from(slice: &'static mut [T]) -> Self {
        Self::new(slice)
    }
}

impl<T> From<MutSliceRef<T>> for &'static mut [T] {
    #[inline(always)]
    fn from(slice: MutSliceRef<T>) -> Self {
        slice.into_mut_slice()
    }
}

impl<T> core::convert::AsRef<[T]> for MutSliceRef<T> {
    #[inline(always)]
    fn as_ref(&self) -> &[T] {
        let union = self.0.union();
        unsafe { union.mut_slice }
    }
}

impl<T> core::convert::AsMut<[T]> for MutSliceRef<T> {
    #[inline(always)]
    fn as_mut(&mut self) -> &mut [T] {
        let union = self.0.union();
        unsafe { union.mut_slice }
    }
}

impl<T> core::borrow::Borrow<[T]> for MutSliceRef<T> {
    #[inline(always)]
    fn borrow(&self) -> &[T] {
        self.as_ref()
    }
}

impl<T> core::borrow::BorrowMut<[T]> for MutSliceRef<T> {
    #[inline(always)]
    fn borrow_mut(&mut self) -> &mut [T] {
        self.as_mut()
    }
}

impl<T> core::ops::Deref for MutSliceRef<T> {
    type Target = [T];

    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        self.as_ref()
    }
}

impl<T> core::ops::DerefMut for MutSliceRef<T> {
    #[inline(always)]
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.as_mut()
    }
}

impl<T> Drop for BoxedSlice<T> {
    #[inline(always)]
    fn drop(&mut self) {
        let union: SliceUnion<'_, _> = self.0.union();
        let boxed: alloc::boxed::Box<[T]> =
            core::mem::ManuallyDrop::into_inner(unsafe { union.boxed });
        drop(boxed);
    }
}

impl<T> BoxedSlice<T> {
    /// Create a new wrapper for a boxed slice `Box<[T]>`.
    #[inline(always)]
    pub fn new(boxed: alloc::boxed::Box<[T]>) -> Self {
        let inner = SliceInner::from_slice(boxed.as_ref());
        let raw = alloc::boxed::Box::into_raw(boxed);
        assert_eq!(inner.ptr, raw as *mut _);
        Self(inner)
    }

    #[inline(always)]
    pub const fn empty() -> Self {
        Self(SliceInner::empty())
    }

    /// Inverse of [`BoxedSlice::new`].
    #[inline(always)]
    pub fn into_boxed_slice(self) -> alloc::boxed::Box<[T]> {
        let union = self.0.union();
        core::mem::ManuallyDrop::into_inner(unsafe { union.boxed })
    }
}

impl<T: Clone> BoxedSlice<T> {
    /// Clone the boxed slice by allocating a new copy.
    #[inline(always)]
    pub fn clone_boxed(&self) -> Self {
        let slice: &[T] = self.as_ref();
        Self::new(slice.into())
    }
}

impl<T: Clone> Clone for BoxedSlice<T> {
    #[inline(always)]
    fn clone(&self) -> Self {
        self.clone_boxed()
    }
}

impl<T> From<alloc::boxed::Box<[T]>> for BoxedSlice<T> {
    #[inline]
    fn from(value: alloc::boxed::Box<[T]>) -> Self {
        Self::new(value)
    }
}

impl<T> From<BoxedSlice<T>> for alloc::boxed::Box<[T]> {
    #[inline(always)]
    fn from(value: BoxedSlice<T>) -> Self {
        value.into_boxed_slice()
    }
}

impl<T> core::convert::AsRef<[T]> for BoxedSlice<T> {
    #[inline(always)]
    fn as_ref(&self) -> &[T] {
        let union = self.0.union();
        unsafe { union.slice }
    }
}

impl<T> core::convert::AsMut<[T]> for BoxedSlice<T> {
    #[inline(always)]
    fn as_mut(&mut self) -> &mut [T] {
        let union = self.0.union();
        unsafe { union.mut_slice }
    }
}

impl<T> core::convert::AsRef<alloc::boxed::Box<[T]>> for BoxedSlice<T> {
    #[inline(always)]
    fn as_ref(&self) -> &alloc::boxed::Box<[T]> {
        unsafe { &*(&self.0 as *const SliceInner<T> as *const alloc::boxed::Box<[T]>) }
    }
}

impl<T> core::convert::AsMut<alloc::boxed::Box<[T]>> for BoxedSlice<T> {
    #[inline(always)]
    fn as_mut(&mut self) -> &mut alloc::boxed::Box<[T]> {
        unsafe { &mut *(&mut self.0 as *mut SliceInner<T> as *mut alloc::boxed::Box<[T]>) }
    }
}

impl<T> core::borrow::Borrow<[T]> for BoxedSlice<T> {
    #[inline(always)]
    fn borrow(&self) -> &[T] {
        self.as_ref()
    }
}

impl<T> core::borrow::BorrowMut<[T]> for BoxedSlice<T> {
    #[inline(always)]
    fn borrow_mut(&mut self) -> &mut [T] {
        self.as_mut()
    }
}

impl<T> core::ops::Deref for BoxedSlice<T> {
    type Target = [T];

    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        self.as_ref()
    }
}

impl<T> core::ops::DerefMut for BoxedSlice<T> {
    #[inline(always)]
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.as_mut()
    }
}

#[repr(C)]
pub(crate) struct SliceInner<T> {
    pub(crate) ptr: *mut T,
    pub(crate) len: usize,
}
static_assertions::assert_eq_size!(SliceInner<u8>, &[u8]);

impl<T> Clone for SliceInner<T> {
    #[inline(always)]
    fn clone(&self) -> Self {
        *self
    }
}

impl<T> Copy for SliceInner<T> {}

impl<T> core::fmt::Debug for SliceInner<T>
where
    T: core::fmt::Debug + 'static,
{
    #[inline(always)]
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        unsafe { self.union().slice.fmt(f) }
    }
}

impl<T> SliceInner<T> {
    #[inline(always)]
    pub(crate) const fn empty() -> Self {
        Self {
            ptr: core::mem::align_of::<T>() as _,
            len: 0,
        }
    }

    #[inline(always)]
    pub(crate) const fn from_slice(slice: &[T]) -> Self {
        Self {
            ptr: slice.as_ptr() as *mut _,
            len: slice.len(),
        }
    }
    #[inline(always)]
    const fn union(self) -> SliceUnion<'static, T> {
        SliceUnion { inner: self }
    }
}

union SliceUnion<'a, T> {
    inner: SliceInner<T>,
    slice: &'a [T],
    mut_slice: &'a mut [T],
    boxed: core::mem::ManuallyDrop<alloc::boxed::Box<[T]>>,
}
static_assertions::assert_eq_size!(SliceInner<u8>, SliceUnion<u8>);