use crate::error::BufferOverflow;
#[allow(private_bounds)]
pub trait Unit: Copy + UnitPrivate {
fn zero() -> Self;
}
impl Unit for u8 {
fn zero() -> Self {
0x0
}
}
impl Unit for u32 {
fn zero() -> Self {
0x0
}
}
pub trait Buffer {
type Unit: Unit;
fn buffer(&self) -> &[Self::Unit];
}
pub trait BufferMut: Buffer {
fn buffer_mut(&mut self) -> &mut [<Self as Buffer>::Unit];
}
pub trait BufferDefault {
fn default() -> Self;
}
pub trait BufferResize {
fn resize(&mut self, size: usize);
}
pub trait BufferTryResize {
fn try_resize(&mut self, size: usize) -> Result<(), BufferOverflow>;
}
pub trait FromBuffer<T>: Sized {
fn from_buffer(value: T) -> Self;
}
pub trait IntoBuffer<T>: Sized {
fn into_buffer(self) -> T;
}
impl<T, U> IntoBuffer<U> for T
where
U: FromBuffer<T>,
{
fn into_buffer(self) -> U {
U::from_buffer(self)
}
}
pub trait TryFromBuffer<T>: Sized {
fn try_from_buffer(value: T) -> Result<Self, crate::error::BufferOverflow>;
}
pub trait TryIntoBuffer<T>: Sized {
fn try_into_buffer(self) -> Result<T, crate::error::BufferOverflow>;
}
impl<T, U> TryIntoBuffer<U> for T
where
U: TryFromBuffer<T>,
{
fn try_into_buffer(self) -> Result<U, crate::error::BufferOverflow> {
U::try_from_buffer(self)
}
}
pub trait Ump: Buffer<Unit = u32> {}
impl<B: Buffer<Unit = u32>> Ump for B {}
pub trait Bytes: Buffer<Unit = u8> {}
impl<B: Buffer<Unit = u8>> Bytes for B {}
impl<U: Unit> Buffer for &[U] {
type Unit = U;
fn buffer(&self) -> &[Self::Unit] {
self
}
}
impl<U: Unit> Buffer for &mut [U] {
type Unit = U;
fn buffer(&self) -> &[Self::Unit] {
self
}
}
impl<U: Unit> BufferMut for &mut [U] {
fn buffer_mut(&mut self) -> &mut [<Self as Buffer>::Unit] {
self
}
}
impl<const SIZE: usize, U: Unit> Buffer for [U; SIZE] {
type Unit = U;
fn buffer(&self) -> &[Self::Unit] {
&self[..]
}
}
impl<const SIZE: usize, U: Unit> BufferMut for [U; SIZE] {
fn buffer_mut(&mut self) -> &mut [<Self as Buffer>::Unit] {
&mut self[..]
}
}
impl<const SIZE: usize, U: Unit> BufferDefault for [U; SIZE] {
fn default() -> Self {
[U::zero(); SIZE]
}
}
impl<const SIZE: usize, U: Unit> BufferTryResize for [U; SIZE] {
fn try_resize(&mut self, size: usize) -> Result<(), BufferOverflow> {
if size > self.len() {
Err(BufferOverflow)
} else {
Ok(())
}
}
}
impl<U: Unit> BufferTryResize for &mut [U] {
fn try_resize(&mut self, size: usize) -> Result<(), BufferOverflow> {
if size > self.len() {
Err(BufferOverflow)
} else {
Ok(())
}
}
}
#[cfg(any(feature = "std", test))]
impl<U: Unit> Buffer for std::vec::Vec<U> {
type Unit = U;
fn buffer(&self) -> &[Self::Unit] {
self
}
}
#[cfg(any(feature = "std", test))]
impl<U: Unit> BufferMut for std::vec::Vec<U> {
fn buffer_mut(&mut self) -> &mut [<Self as Buffer>::Unit] {
self
}
}
#[cfg(any(feature = "std", test))]
impl<U: Unit> BufferResize for std::vec::Vec<U> {
fn resize(&mut self, size: usize) {
self.resize(size, U::zero());
}
}
#[cfg(any(feature = "std", test))]
impl<U: Unit> BufferDefault for std::vec::Vec<U> {
fn default() -> Self {
Default::default()
}
}
#[cfg(any(feature = "std", test))]
impl<U: Unit> Buffer for &mut std::vec::Vec<U> {
type Unit = U;
fn buffer(&self) -> &[Self::Unit] {
self
}
}
#[cfg(any(feature = "std", test))]
impl<U: Unit> BufferMut for &mut std::vec::Vec<U> {
fn buffer_mut(&mut self) -> &mut [<Self as Buffer>::Unit] {
self
}
}
#[cfg(any(feature = "std", test))]
impl<U: Unit> BufferResize for &mut std::vec::Vec<U> {
fn resize(&mut self, size: usize) {
std::vec::Vec::resize(*self, size, U::zero());
}
}
impl<const SIZE: usize, U: Unit> TryFromBuffer<&[U]> for [U; SIZE] {
fn try_from_buffer(value: &[U]) -> Result<Self, crate::error::BufferOverflow> {
if value.len() > SIZE {
return Err(crate::error::BufferOverflow);
}
let mut buffer = [U::zero(); SIZE];
buffer[..value.len()].copy_from_slice(value);
Ok(buffer)
}
}
impl<const SIZE: usize, U: Unit> TryFromBuffer<&mut [U]> for [U; SIZE] {
fn try_from_buffer(value: &mut [U]) -> Result<Self, crate::error::BufferOverflow> {
if value.len() > SIZE {
return Err(crate::error::BufferOverflow);
}
let mut buffer = [U::zero(); SIZE];
buffer[..value.len()].copy_from_slice(value);
Ok(buffer)
}
}
#[cfg(any(feature = "std", test))]
impl<const SIZE: usize, U: Unit> TryFromBuffer<std::vec::Vec<U>> for [U; SIZE] {
fn try_from_buffer(value: std::vec::Vec<U>) -> Result<Self, crate::error::BufferOverflow> {
if value.len() > SIZE {
return Err(crate::error::BufferOverflow);
}
let mut buffer = [U::zero(); SIZE];
buffer[..value.len()].copy_from_slice(&value[..]);
Ok(buffer)
}
}
impl<'a, U: Unit> FromBuffer<&'a mut [U]> for &'a [U] {
fn from_buffer(value: &'a mut [U]) -> Self {
value
}
}
#[cfg(any(feature = "std", test))]
impl<U: Unit, const SIZE: usize> FromBuffer<[U; SIZE]> for std::vec::Vec<U> {
fn from_buffer(value: [U; SIZE]) -> Self {
value.to_vec()
}
}
#[cfg(any(feature = "std", test))]
impl<U: Unit> FromBuffer<&[U]> for std::vec::Vec<U> {
fn from_buffer(value: &[U]) -> Self {
value.to_vec()
}
}
#[cfg(any(feature = "std", test))]
impl<U: Unit> FromBuffer<&mut [U]> for std::vec::Vec<U> {
fn from_buffer(value: &mut [U]) -> Self {
value.to_vec()
}
}
pub(crate) const UNIT_ID_U8: u8 = 0;
pub(crate) const UNIT_ID_U32: u8 = 1;
pub(crate) trait UnitPrivate: Copy {
const UNIT_ID: u8;
fn specialise_buffer_u8(buffer: &[Self]) -> &[u8];
fn specialise_buffer_u8_mut(buffer: &mut [Self]) -> &mut [u8];
fn specialise_buffer_u32(buffer: &[Self]) -> &[u32];
fn specialise_buffer_u32_mut(buffer: &mut [Self]) -> &mut [u32];
}
impl UnitPrivate for u8 {
const UNIT_ID: u8 = 0;
fn specialise_buffer_u8(buffer: &[Self]) -> &[u8] {
buffer
}
fn specialise_buffer_u8_mut(buffer: &mut [Self]) -> &mut [u8] {
buffer
}
fn specialise_buffer_u32(_: &[Self]) -> &[u32] {
unreachable!()
}
fn specialise_buffer_u32_mut(_: &mut [Self]) -> &mut [u32] {
unreachable!()
}
}
impl UnitPrivate for u32 {
const UNIT_ID: u8 = 1;
fn specialise_buffer_u8(_: &[Self]) -> &[u8] {
unreachable!()
}
fn specialise_buffer_u8_mut(_: &mut [Self]) -> &mut [u8] {
unreachable!()
}
fn specialise_buffer_u32(buffer: &[Self]) -> &[u32] {
buffer
}
fn specialise_buffer_u32_mut(buffer: &mut [Self]) -> &mut [u32] {
buffer
}
}
pub(crate) trait SpecialiseU32<B: Buffer> {
fn specialise_u32(&self) -> &[u32];
fn specialise_u32_mut(&mut self) -> &mut [u32]
where
B: BufferMut;
}
impl<B: Buffer> SpecialiseU32<B> for B {
fn specialise_u32(&self) -> &[u32] {
match B::Unit::UNIT_ID {
UNIT_ID_U32 => <B::Unit as UnitPrivate>::specialise_buffer_u32(self.buffer()),
_ => unreachable!(),
}
}
fn specialise_u32_mut(&mut self) -> &mut [u32]
where
B: BufferMut,
{
match B::Unit::UNIT_ID {
UNIT_ID_U32 => <B::Unit as UnitPrivate>::specialise_buffer_u32_mut(self.buffer_mut()),
_ => unreachable!(),
}
}
}
pub(crate) trait SpecialiseU8<B: Buffer> {
fn specialise_u8(&self) -> &[u8];
fn specialise_u8_mut(&mut self) -> &mut [u8]
where
B: BufferMut;
}
impl<B: Buffer> SpecialiseU8<B> for B {
fn specialise_u8(&self) -> &[u8] {
match B::Unit::UNIT_ID {
UNIT_ID_U8 => <B::Unit as UnitPrivate>::specialise_buffer_u8(self.buffer()),
_ => unreachable!(),
}
}
fn specialise_u8_mut(&mut self) -> &mut [u8]
where
B: BufferMut,
{
match B::Unit::UNIT_ID {
UNIT_ID_U8 => <B::Unit as UnitPrivate>::specialise_buffer_u8_mut(self.buffer_mut()),
_ => unreachable!(),
}
}
}