#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::rc::Rc;
#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "alloc")]
use alloc::sync::Arc;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::mem::MaybeUninit;
use core::slice;
use crate::error::InvalidInput;
#[allow(private_bounds, reason = "Sealed trait.")]
pub(crate) trait OwnedUninitBuf<T> {
#[doc(hidden)]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>];
#[allow(unsafe_code, reason = "XXX")]
#[doc(hidden)]
unsafe fn assume_init(self) -> T;
}
impl<const N: usize> OwnedUninitBuf<[u8; N]> for [MaybeUninit<u8>; N] {
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
self
}
#[allow(unsafe_code, reason = "XXX")]
#[inline]
unsafe fn assume_init(self) -> [u8; N] {
unsafe { *((&raw const self).cast()) }
}
}
#[cfg(feature = "alloc")]
impl OwnedUninitBuf<Vec<u8>> for Box<[MaybeUninit<u8>]> {
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
&mut self[..]
}
#[allow(unsafe_code, reason = "XXX")]
#[inline]
unsafe fn assume_init(self) -> Vec<u8> {
unsafe { self.assume_init().into_vec() }
}
}
#[cfg(feature = "alloc")]
impl OwnedUninitBuf<Box<[u8]>> for Box<[MaybeUninit<u8>]> {
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
&mut self[..]
}
#[allow(unsafe_code, reason = "XXX")]
#[inline]
unsafe fn assume_init(self) -> Box<[u8]> {
unsafe { self.assume_init() }
}
}
#[cfg(feature = "alloc")]
impl OwnedUninitBuf<Arc<[u8]>> for Arc<[MaybeUninit<u8>]> {
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
Self::make_mut(self)
}
#[allow(unsafe_code, reason = "XXX")]
#[inline]
unsafe fn assume_init(self) -> Arc<[u8]> {
unsafe { self.assume_init() }
}
}
#[cfg(feature = "alloc")]
impl OwnedUninitBuf<Rc<[u8]>> for Rc<[MaybeUninit<u8>]> {
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
Self::make_mut(self)
}
#[allow(unsafe_code, reason = "XXX")]
#[inline]
unsafe fn assume_init(self) -> Rc<[u8]> {
unsafe { self.assume_init() }
}
}
#[allow(private_bounds, reason = "Sealed trait.")]
pub trait OwnedBuf: Sealed + Sized {
#[doc(hidden)]
type Uninit: OwnedUninitBuf<Self>;
#[doc(hidden)]
fn new_uninit_slice(len: usize) -> Result<Self::Uninit, InvalidInput>;
}
impl<const N: usize> OwnedBuf for [u8; N] {
type Uninit = [MaybeUninit<u8>; N];
#[inline]
fn new_uninit_slice(len: usize) -> Result<Self::Uninit, InvalidInput> {
if len != N {
return Err(InvalidInput);
}
Ok([MaybeUninit::uninit(); N])
}
}
#[cfg(feature = "alloc")]
impl OwnedBuf for Vec<u8> {
type Uninit = Box<[MaybeUninit<u8>]>;
#[inline]
fn new_uninit_slice(len: usize) -> Result<Self::Uninit, InvalidInput> {
Ok(Box::new_uninit_slice(len))
}
}
#[cfg(feature = "alloc")]
impl OwnedBuf for Box<[u8]> {
type Uninit = Box<[MaybeUninit<u8>]>;
#[inline]
fn new_uninit_slice(len: usize) -> Result<Self::Uninit, InvalidInput> {
Ok(Self::new_uninit_slice(len))
}
}
#[cfg(feature = "alloc")]
impl OwnedBuf for Arc<[u8]> {
type Uninit = Arc<[MaybeUninit<u8>]>;
#[inline]
fn new_uninit_slice(len: usize) -> Result<Self::Uninit, InvalidInput> {
Ok(Self::new_uninit_slice(len))
}
}
#[cfg(feature = "alloc")]
impl OwnedBuf for Rc<[u8]> {
type Uninit = Rc<[MaybeUninit<u8>]>;
#[inline]
fn new_uninit_slice(len: usize) -> Result<Self::Uninit, InvalidInput> {
Ok(Self::new_uninit_slice(len))
}
}
#[allow(private_bounds, reason = "Sealed trait.")]
pub trait StringBuf: Sealed {
#[doc(hidden)]
type Buf: OwnedBuf;
#[allow(unsafe_code, reason = "XXX")]
#[doc(hidden)]
unsafe fn from_utf8_unchecked(buf: Self::Buf) -> Self;
}
impl<T> StringBuf for T
where
T: OwnedBuf,
{
type Buf = Self;
#[allow(unsafe_code, reason = "XXX")]
#[inline]
unsafe fn from_utf8_unchecked(buf: Self::Buf) -> Self {
buf
}
}
#[cfg(feature = "alloc")]
impl StringBuf for String {
type Buf = Vec<u8>;
#[allow(unsafe_code, reason = "XXX")]
#[inline]
unsafe fn from_utf8_unchecked(buf: Self::Buf) -> Self {
unsafe { Self::from_utf8_unchecked(buf) }
}
}
#[cfg(feature = "alloc")]
impl StringBuf for Box<str> {
type Buf = Box<[u8]>;
#[allow(unsafe_code, reason = "XXX")]
#[inline]
unsafe fn from_utf8_unchecked(buf: Self::Buf) -> Self {
unsafe { Self::from_raw(Box::into_raw(buf) as *mut str) }
}
}
#[cfg(feature = "alloc")]
impl StringBuf for Arc<str> {
type Buf = Arc<[u8]>;
#[allow(unsafe_code, reason = "XXX")]
#[inline]
unsafe fn from_utf8_unchecked(buf: Self::Buf) -> Self {
unsafe { Self::from_raw(Arc::into_raw(buf) as *const str) }
}
}
#[cfg(feature = "alloc")]
impl StringBuf for Rc<str> {
type Buf = Rc<[u8]>;
#[allow(unsafe_code, reason = "XXX")]
#[inline]
unsafe fn from_utf8_unchecked(buf: Self::Buf) -> Self {
unsafe { Self::from_raw(Rc::into_raw(buf) as *const str) }
}
}
#[allow(private_bounds, reason = "Sealed trait.")]
pub trait Buf: Sealed {
#[doc(hidden)]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>];
#[allow(unsafe_code, reason = "See below.")]
#[doc(hidden)]
unsafe fn assume_init_ref(&mut self, additional: usize) -> &[u8];
}
impl<T> Buf for &mut T
where
T: Buf,
{
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
Buf::as_uninit(*self)
}
#[inline]
#[allow(unsafe_code, reason = "XXX")]
unsafe fn assume_init_ref(&mut self, additional: usize) -> &[u8] {
unsafe { Buf::assume_init_ref(*self, additional) }
}
}
impl Buf for [MaybeUninit<u8>] {
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
self
}
#[inline]
#[allow(unsafe_code, reason = "XXX")]
unsafe fn assume_init_ref(&mut self, additional: usize) -> &[u8] {
debug_assert!(additional <= self.len());
unsafe { slice::from_raw_parts(self.as_ptr().cast(), additional) }
}
}
impl<const N: usize> Buf for [MaybeUninit<u8>; N] {
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
self
}
#[inline]
#[allow(unsafe_code, reason = "XXX")]
unsafe fn assume_init_ref(&mut self, additional: usize) -> &[u8] {
debug_assert!(additional <= N);
unsafe { slice::from_raw_parts(self.as_ptr().cast(), additional) }
}
}
impl Buf for [u8] {
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
#[allow(unsafe_code, reason = "XXX")]
unsafe {
&mut *((&raw mut *self) as *mut [MaybeUninit<u8>])
}
}
#[inline]
#[allow(unsafe_code, reason = "XXX")]
unsafe fn assume_init_ref(&mut self, additional: usize) -> &[u8] {
debug_assert!(additional <= self.len());
unsafe { slice::from_raw_parts(self.as_ptr(), additional) }
}
}
impl<const N: usize> Buf for [u8; N] {
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
#[allow(unsafe_code, reason = "XXX")]
unsafe {
&mut *((&raw mut *self).cast::<[MaybeUninit<u8>; N]>())
}
}
#[inline]
#[allow(unsafe_code, reason = "XXX")]
unsafe fn assume_init_ref(&mut self, additional: usize) -> &[u8] {
debug_assert!(additional <= N);
unsafe { slice::from_raw_parts(self.as_ptr(), additional) }
}
}
#[cfg(feature = "alloc")]
impl Buf for Vec<u8> {
#[inline]
fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
self.spare_capacity_mut()
}
#[inline]
#[allow(unsafe_code, reason = "XXX")]
unsafe fn assume_init_ref(&mut self, additional: usize) -> &[u8] {
let len = self.len();
unsafe {
self.set_len(len + additional);
}
&self[len..]
}
}
trait Sealed {}
impl<const N: usize> Sealed for [MaybeUninit<u8>; N] {}
#[cfg(feature = "alloc")]
impl Sealed for Vec<u8> {}
#[cfg(feature = "alloc")]
impl Sealed for Box<[MaybeUninit<u8>]> {}
#[cfg(feature = "alloc")]
impl Sealed for Arc<[MaybeUninit<u8>]> {}
#[cfg(feature = "alloc")]
impl Sealed for Rc<[MaybeUninit<u8>]> {}
impl<const N: usize> Sealed for [u8; N] {}
#[cfg(feature = "alloc")]
impl Sealed for Box<[u8]> {}
#[cfg(feature = "alloc")]
impl Sealed for Arc<[u8]> {}
#[cfg(feature = "alloc")]
impl Sealed for Rc<[u8]> {}
#[cfg(feature = "alloc")]
impl Sealed for String {}
#[cfg(feature = "alloc")]
impl Sealed for Box<str> {}
#[cfg(feature = "alloc")]
impl Sealed for Arc<str> {}
#[cfg(feature = "alloc")]
impl Sealed for Rc<str> {}
impl<T: Sealed> Sealed for &mut T {}
impl Sealed for [MaybeUninit<u8>] {}
impl Sealed for [u8] {}