use core::{mem::MaybeUninit, slice};
pub struct Writer<'buf> {
buf: &'buf mut [MaybeUninit<u8>],
pos: usize,
}
impl<'buf> Writer<'buf> {
#[inline]
pub(crate) fn new(buf: &'buf mut [MaybeUninit<u8>]) -> Self {
Self { buf, pos: 0 }
}
#[inline]
pub(crate) fn remaining(&self) -> usize {
self.buf.len() - self.pos
}
#[inline]
fn as_mut_ptr(&mut self) -> *mut u8 {
debug_assert!(self.pos <= self.buf.len(), "writer invariant violation");
let ptr: *mut u8 = self.buf.as_mut_ptr().cast();
unsafe { ptr.add(self.pos) }
}
#[inline]
pub(crate) unsafe fn write_slice(&mut self, s: &[u8]) {
debug_assert!(self.remaining() >= s.len(), "writer invariant violation");
let ptr = self.as_mut_ptr();
unsafe { ptr.copy_from_nonoverlapping(s.as_ptr(), s.len()) }
self.pos += s.len();
}
#[inline]
pub(crate) unsafe fn write_byte(&mut self, u: u8) {
debug_assert!(
self.remaining() >= size_of::<u8>(),
"writer invariant violation",
);
let ptr = self.as_mut_ptr();
unsafe { ptr.write(u) }
self.pos += size_of::<u8>();
}
#[inline]
pub(crate) unsafe fn init(self) -> &'buf mut [u8] {
debug_assert_eq!(self.remaining(), 0, "writer invariant violation");
unsafe { slice::from_raw_parts_mut(self.buf.as_mut_ptr().cast(), self.buf.len()) }
}
}