use crate::{Error, Result};
use core::cell::Cell;
use core::fmt::{Debug, Formatter};
pub struct Dstream<'a> {
pub(in crate) data: &'a [u8],
pub(in crate) pos: Cell<usize>,
}
impl<'a> Dstream<'a> {
#[inline(always)]
#[must_use]
pub const fn new(data: &'a [u8]) -> Self { Self { data, pos: Cell::new(0x0) } }
#[inline]
pub fn read(&self, count: usize) -> Result<&[u8]> {
let rem = self.data.len() - self.pos.get();
let req = count;
if rem < req { return Err(Error::EndOfStream { req, rem }) }
let start = self.pos.get();
let stop = start + req;
self.pos.set(stop);
let data = &self.data[start..stop];
Ok(data)
}
#[inline(always)]
#[must_use]
pub const fn as_ptr(&self) -> *const u8 { self.data.as_ptr() }
#[inline(always)]
#[must_use]
pub const fn as_slice(&self) -> &[u8] {
let ptr = self.as_ptr();
let len = self.len();
unsafe { core::slice::from_raw_parts(ptr, len) }
}
#[inline(always)]
#[must_use]
pub const fn len(&self) -> usize { unsafe { self.pos.as_ptr().read() } }
#[inline(always)]
#[must_use]
pub const fn is_empty(&self) -> bool { self.len() == 0x0 }
#[inline(always)]
#[must_use]
pub const fn is_full(&self) -> bool { self.len() == self.data.len() }
}
impl Debug for Dstream<'_> {
#[inline(always)]
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { Debug::fmt(self.as_slice(), f) }
}
impl<'a> From<&'a [u8]> for Dstream<'a> {
#[inline(always)]
fn from(value: &'a [u8]) -> Self { Self::new(value) }
}
impl<'a> From<&'a mut [u8]> for Dstream<'a> {
#[inline(always)]
fn from(value: &'a mut [u8]) -> Self { Self::new(value) }
}
impl PartialEq for Dstream<'_> {
#[inline(always)]
fn eq(&self, other: &Self) -> bool { self.as_slice() == other.as_slice() }
}
impl PartialEq<&[u8]> for Dstream<'_> {
#[inline(always)]
fn eq(&self, other: &&[u8]) -> bool { self.as_slice() == *other }
}
impl<const N: usize> PartialEq<[u8; N]> for Dstream<'_> {
#[inline(always)]
fn eq(&self, other: &[u8; N]) -> bool { self.as_slice() == other.as_slice() }
}