utf8proc 0.1.2

Rust bindings to the utf8proc library
Documentation
//! Implements the [`MaybeUninitSliceExt`] extension type.

use std::mem::MaybeUninit;

/// A buffer which has been split into initialized and uninitialized parts.
///
/// See [`MaybeUninitSlice`] and [`MaybeUninitSliceExt`].
pub type SplitInitBuffer<'a, T> = (&'a mut [T], &'a mut MaybeUninitSlice<T>);

/// A slice of data whose elements may or may not be initialized.
///
/// Newtype wrapper around [`[MaybeUninit<T>]`](MaybeUninit),
/// with extension methods available through [`MaybeUninitSliceExt`]
pub type MaybeUninitSlice<T> = [MaybeUninit<T>];
/// Extension methods for a [`MaybeUninitSlice`] (`[MaybeUninit<T>]`).
///
/// Contains functionality not yet available on stable rust.
pub trait MaybeUninitSliceExt<T>: sealed::Sealed<T> {
    /// Convert a mutable reference to an uninitialized array,
    /// into a mutable reference to an uninitialized slice.
    ///
    /// If you have an `[MaybeUninit<T>; N]` instead,
    /// you can use a deref conversion.
    fn from_uninit_array_mut<const N: usize>(array: &mut MaybeUninit<[T; N]>) -> &mut Self;

    /// Convert a reference to an uninitialized array,
    /// into a reference to an uninitialized slice.
    ///
    /// If you have an `[MaybeUninit<T>; N]` instead,
    /// you can use a deref conversion.
    fn from_uninit_array_ref<const N: usize>(array: &MaybeUninit<[T; N]>) -> &Self;

    /// Convert a slice of initialized data into a slice of uninitialized data.
    ///
    /// This is safe, because it is removing guarantees, not adding them.
    /// There is no chance of double-initialization or leaks,
    /// because the slice is a shared reference (not mutable)
    fn from_init_slice(slice: &[T]) -> &Self;

    /// Convert a mutable slice of initialized data into a slice of uninitialized data.
    ///
    /// This is safe, because it is removing guarantees, not adding them.
    /// Because of the requirement `T: Copy`, there is no chance of double-initialization or leaks.
    fn from_init_slice_mut(slice: &mut [T]) -> &mut Self
    where
        T: Copy;

    /// Assume the data in the slice is fully initialized.
    ///
    /// Stable alternative to [`slice::assume_init_ref`].
    ///
    /// ## Safety
    /// Calling this when the content is not yet fully initialized causes undefined behavior.
    #[inline]
    unsafe fn assume_init_ref(&self) -> &[T] {
        // SAFETY: The
        unsafe { std::slice::from_raw_parts(self.as_slice().as_ptr().cast(), self.as_slice().len()) }
    }

    /// Assume the data in the slice is fully initialized.
    ///
    /// Stable alternative to [`slice::assume_init_mut`].
    ///
    /// ## Safety
    /// Calling this when the content is not yet fully initialized causes undefined behavior.
    #[inline]
    unsafe fn assume_init_mut(&mut self) -> &mut [T] {
        let len = self.as_slice().len();
        // SAFETY: CAller guarantees data is initialized
        unsafe { std::slice::from_raw_parts_mut(self.as_mut_slice().as_mut_ptr().cast(), len) }
    }
}
impl<T> MaybeUninitSliceExt<T> for MaybeUninitSlice<T> {
    #[inline]
    fn from_uninit_array_mut<const N: usize>(array: &mut MaybeUninit<[T; N]>) -> &mut Self {
        // SAFETY: Array is valid ref, length is constant
        unsafe { std::slice::from_raw_parts_mut(array.as_mut_ptr().cast::<MaybeUninit<T>>(), N) }
    }

    #[inline]
    fn from_uninit_array_ref<const N: usize>(array: &MaybeUninit<[T; N]>) -> &Self {
        // SAFETY: Array is valid ref, length is constant
        unsafe { std::slice::from_raw_parts(array.as_ptr().cast::<MaybeUninit<T>>(), N) }
    }

    #[inline]
    fn from_init_slice(slice: &[T]) -> &Self {
        // SAFETY: Just forgetting initialization, not adding it
        unsafe { std::slice::from_raw_parts(slice.as_ptr().cast::<MaybeUninit<T>>(), slice.len()) }
    }

    #[inline]
    fn from_init_slice_mut(slice: &mut [T]) -> &mut MaybeUninitSlice<T>
    where
        T: Copy,
    {
        // SAFETY: Just forgetting initialization, not adding it, T: Copy means no leaks
        unsafe { std::slice::from_raw_parts_mut(slice.as_mut_ptr().cast::<MaybeUninit<T>>(), slice.len()) }
    }
}

mod sealed {
    use super::MaybeUninitSlice;
    use std::mem::MaybeUninit;

    pub trait Sealed<T> {
        fn as_slice(&self) -> &[MaybeUninit<T>];
        fn as_mut_slice(&mut self) -> &mut [MaybeUninit<T>];
    }
    impl<T> Sealed<T> for MaybeUninitSlice<T> {
        #[inline]
        fn as_slice(&self) -> &[MaybeUninit<T>] {
            self
        }

        #[inline]
        fn as_mut_slice(&mut self) -> &mut [MaybeUninit<T>] {
            self
        }
    }
}