#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::{mem, num::NonZeroUsize, option};
use crate::{
buffer::{Buffer, SplitBuffer},
reader::HasReader,
writer::{BacktrackableWriter, DidntWrite, HasWriter, Writer},
};
#[must_use]
pub fn uninit(capacity: usize) -> Vec<u8> {
let mut vbuf = Vec::with_capacity(capacity);
#[allow(clippy::uninit_vec)]
unsafe {
vbuf.set_len(capacity);
}
vbuf
}
impl Buffer for Vec<u8> {
fn len(&self) -> usize {
Vec::len(self)
}
}
impl Buffer for &Vec<u8> {
fn len(&self) -> usize {
Vec::len(self)
}
}
impl Buffer for &mut Vec<u8> {
fn len(&self) -> usize {
Vec::len(self)
}
}
impl SplitBuffer for Vec<u8> {
type Slices<'a> = option::IntoIter<&'a [u8]>;
fn slices(&self) -> Self::Slices<'_> {
Some(self.as_slice()).into_iter()
}
}
impl HasWriter for &mut Vec<u8> {
type Writer = Self;
fn writer(self) -> Self::Writer {
self
}
}
impl Writer for &mut Vec<u8> {
fn write(&mut self, bytes: &[u8]) -> Result<NonZeroUsize, DidntWrite> {
if bytes.is_empty() {
return Err(DidntWrite);
}
self.extend_from_slice(bytes);
Ok(unsafe { NonZeroUsize::new_unchecked(bytes.len()) })
}
fn write_exact(&mut self, bytes: &[u8]) -> Result<(), DidntWrite> {
self.write(bytes).map(|_| ())
}
fn write_u8(&mut self, byte: u8) -> Result<(), DidntWrite> {
self.push(byte);
Ok(())
}
fn remaining(&self) -> usize {
usize::MAX
}
unsafe fn with_slot<F>(&mut self, mut len: usize, write: F) -> Result<NonZeroUsize, DidntWrite>
where
F: FnOnce(&mut [u8]) -> usize,
{
self.reserve(len);
let s = crate::unsafe_slice_mut!(self.spare_capacity_mut(), ..len);
len = unsafe { write(&mut *(s as *mut [mem::MaybeUninit<u8>] as *mut [u8])) };
unsafe { self.set_len(self.len() + len) };
NonZeroUsize::new(len).ok_or(DidntWrite)
}
}
impl BacktrackableWriter for &mut Vec<u8> {
type Mark = usize;
fn mark(&mut self) -> Self::Mark {
self.len()
}
fn rewind(&mut self, mark: Self::Mark) -> bool {
self.truncate(mark);
true
}
}
impl<'a> HasReader for &'a Vec<u8> {
type Reader = &'a [u8];
fn reader(self) -> Self::Reader {
self
}
}