use core::mem::MaybeUninit;
use core::slice;
pub trait Buffer {
fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>];
#[allow(unsafe_code, reason = "See below.")]
unsafe fn advance(&mut self, additional: usize) -> &[u8];
}
impl<T: Buffer> Buffer for &mut T {
#[inline]
fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
Buffer::spare_capacity_mut(*self)
}
#[inline]
#[allow(unsafe_code, reason = "XXX")]
unsafe fn advance(&mut self, additional: usize) -> &[u8] {
unsafe { Buffer::advance(*self, additional) }
}
}
impl Buffer for [MaybeUninit<u8>] {
#[inline]
fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
self
}
#[inline]
#[allow(unsafe_code, reason = "XXX")]
unsafe fn advance(&mut self, additional: usize) -> &[u8] {
debug_assert!(additional <= self.len());
unsafe { slice::from_raw_parts(self.as_ptr().cast(), additional) }
}
}
impl<const N: usize> Buffer for [MaybeUninit<u8>; N] {
#[inline]
fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
self
}
#[inline]
#[allow(unsafe_code, reason = "XXX")]
unsafe fn advance(&mut self, additional: usize) -> &[u8] {
debug_assert!(additional <= N);
unsafe { slice::from_raw_parts(self.as_ptr().cast(), additional) }
}
}
impl Buffer for [u8] {
#[inline]
fn spare_capacity_mut(&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 advance(&mut self, additional: usize) -> &[u8] {
debug_assert!(additional <= self.len());
unsafe { slice::from_raw_parts(self.as_ptr(), additional) }
}
}
impl<const N: usize> Buffer for [u8; N] {
#[inline]
fn spare_capacity_mut(&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 advance(&mut self, additional: usize) -> &[u8] {
debug_assert!(additional <= N);
unsafe { slice::from_raw_parts(self.as_ptr(), additional) }
}
}
#[cfg(feature = "alloc")]
impl Buffer for alloc::vec::Vec<u8> {
#[inline]
fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
self.spare_capacity_mut()
}
#[inline]
#[allow(unsafe_code, reason = "XXX")]
unsafe fn advance(&mut self, additional: usize) -> &[u8] {
let len = self.len();
unsafe {
self.set_len(len + additional);
}
&self[len..]
}
}