use core::{fmt, marker, mem, ptr, slice, str};
const _STATIC_ASSERT: () = assert!(!mem::needs_drop::<u8>(), "u8 never needs drop");
#[derive(Debug)]
pub struct UninitWriter<'a> {
pointer: *mut u8,
capacity: usize,
_lifetime: marker::PhantomData<&'a mut u8>,
}
impl<'a> UninitWriter<'a> {
#[inline]
pub const fn new<const N: usize>(buffer: &'a mut mem::MaybeUninit<[u8; N]>) -> Self {
Self {
pointer: buffer.as_mut_ptr().cast::<u8>(),
capacity: N,
_lifetime: marker::PhantomData,
}
}
#[inline]
pub const fn fill_and_finish(self, filler: u8) {
unsafe { ptr::write_bytes(self.pointer, filler, self.capacity) };
}
#[inline]
pub const fn write_str_truncated(&mut self, s: &str) -> usize {
let len = floor_char_boundary(s, self.capacity);
unsafe { self.write_unchecked(slice::from_raw_parts(s.as_ptr(), len)) };
len
}
#[inline]
const unsafe fn write_unchecked(&mut self, bytes: &[u8]) {
debug_assert!(bytes.len() <= self.capacity);
unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), self.pointer, bytes.len()) };
self.capacity -= bytes.len();
self.pointer = unsafe { self.pointer.add(bytes.len()) };
}
}
impl fmt::Write for UninitWriter<'_> {
fn write_str(&mut self, s: &str) -> fmt::Result {
if s.len() <= self.capacity {
unsafe { self.write_unchecked(s.as_bytes()) };
Ok(())
} else {
Err(fmt::Error)
}
}
}
#[inline]
const fn floor_char_boundary(s: &str, index: usize) -> usize {
#[inline]
const fn is_utf8_char_boundary(byte: u8) -> bool {
(byte as i8) >= -0x40 }
if index >= s.len() {
s.len()
} else {
let mut i = index;
if i > 0 && !is_utf8_char_boundary(s.as_bytes()[i]) {
i -= 1;
if i > 0 && !is_utf8_char_boundary(s.as_bytes()[i]) {
i -= 1;
if !is_utf8_char_boundary(s.as_bytes()[i]) {
debug_assert!(i > 0);
i -= 1;
debug_assert!(is_utf8_char_boundary(s.as_bytes()[i]));
}
}
}
i
}
}