use std::{marker, mem};
use crate::{buffer, buffer::storage::provided::view::LengthError};
#[derive(Clone, Copy, Eq, PartialEq)]
#[repr(transparent)]
pub struct Limit<'id> {
resident: u32,
operation: marker::PhantomData<fn(&'id mut ()) -> &'id mut ()>,
}
impl<'id> Limit<'id> {
pub const fn get(self) -> u32 {
self.resident
}
pub unsafe fn project<'a>(self, bytes: &'a mut [u8]) -> buffer::raw::Projection<'a, 'id> {
buffer::raw::Projection {
bytes,
operation: self.operation,
}
}
}
impl Limit<'_> {
pub(in crate::buffer) fn scope<R>(
resident: u32,
apply: impl for<'id> FnOnce(Limit<'id>) -> R,
) -> R {
apply(Limit {
resident,
operation: marker::PhantomData,
})
}
}
const _: () = {
assert!(mem::size_of::<Limit<'static>>() == mem::size_of::<u32>());
assert!(
mem::size_of::<buffer::raw::Projection<'static, 'static>>() == 2 * mem::size_of::<usize>()
);
};
impl<'id> Limit<'id> {
pub fn try_project<'a>(
self,
bytes: &'a mut [u8],
) -> Result<buffer::raw::Projection<'a, 'id>, LengthError> {
if bytes.len() > self.get() as usize {
return Err(LengthError::new(bytes.len(), self.get()));
}
Ok(unsafe { self.project(bytes) })
}
}