use crate::Output;
use core::{cell::Cell, mem::MaybeUninit};
pub(crate) struct MaybeUninitBufferWriter<'a> {
buffer: &'a mut [MaybeUninit<u8>],
offset: usize,
skip: usize,
}
impl<'a> MaybeUninitBufferWriter<'a> {
pub(crate) fn new(buffer: &'a mut [MaybeUninit<u8>]) -> Self {
Self {
buffer,
offset: 0,
skip: 0,
}
}
pub(crate) fn with_buffer<T>(&self, f: impl FnOnce(&'a [u8]) -> T) -> T {
f(self.buffer_slice())
}
fn buffer_slice(&self) -> &'a [u8] {
unsafe {
&*(&self.buffer[0..self.offset] as *const _ as *const [u8])
}
}
pub(crate) fn skip_next(&mut self, skip: usize) {
self.skip = skip;
}
}
impl Output for MaybeUninitBufferWriter<'_> {
fn write(&mut self, bytes: &[u8]) {
debug_assert!(
self.skip <= bytes.len(),
"Skip value must be less than or equal to the length of the bytes slice"
);
let write_len = bytes
.len()
.checked_sub(self.skip)
.expect("skip exceeds bytes length");
let end_offset = self
.offset
.checked_add(write_len)
.expect("buffer write offset overflow");
let this = self
.buffer
.get_mut(self.offset..end_offset)
.expect("buffer too small for encoded bytes");
this.write_copy_of_slice(&bytes[self.skip..]);
self.offset = end_offset;
self.skip = 0;
}
}
pub(crate) struct SyncCell<T: ?Sized>(Cell<T>);
unsafe impl<T: ?Sized + Sync> Sync for SyncCell<T> {}
#[allow(unused)]
impl<T> SyncCell<T> {
pub const fn new(value: T) -> Self {
Self(Cell::new(value))
}
pub fn get(&self) -> T
where
T: Copy,
{
self.0.get()
}
pub fn set(&self, value: T) {
self.0.set(value);
}
pub fn replace(&self, val: T) -> T {
self.0.replace(val)
}
pub fn into_inner(self) -> T {
self.0.into_inner()
}
}