#![no_std]
use core::mem::MaybeUninit;
mod util;
pub struct Cursor<'a, T, const N: usize> {
slice: &'a mut [MaybeUninit<T>; N],
}
impl<'a, T, const N: usize> Cursor<'a, T, N> {
pub fn new(slice: &'a mut [MaybeUninit<T>; N]) -> Self {
Self { slice }
}
fn write_impl(&mut self, value: [T; N]) {
*self.slice = unsafe {
let ptr = &value as *const [T; N] as *const [MaybeUninit<T>; N];
let read_value = core::ptr::read(ptr);
core::mem::drop(value);
read_value
};
}
pub fn finish(mut self, value: [T; N]) {
self.write_impl(value);
core::mem::forget(self);
}
pub fn write<const L: usize, const R: usize>(self, value: [T; L]) -> Cursor<'a, T, R> {
let (l, r) = self.split::<L, R>();
l.finish(value);
r
}
unsafe fn into_buf(self) -> &'a mut [MaybeUninit<T>; N] {
core::mem::transmute(self)
}
pub fn split<const L: usize, const R: usize>(self) -> (Cursor<'a, T, L>, Cursor<'a, T, R>) {
let buf = unsafe { self.into_buf() };
let (l, r) = crate::util::split_mut::<_, N, L, R>(buf);
(Cursor { slice: l }, Cursor { slice: r })
}
pub fn assert_size<const M: usize>(self) -> Cursor<'a, T, M> {
let (l, _) = self.split::<M, 0>();
l
}
}
impl<'a, T, const N: usize> Drop for Cursor<'a, T, N> {
fn drop(&mut self) {
if N > 0 {
panic!("Cursor still has uninitialized bytes");
}
}
}