#[cfg(test)]
#[path = "../../tests/bytes/fixed.rs"]
mod tests;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::hash::{Hash, Hasher};
use crate::bytes::common::ByteBuffer;
#[derive(Clone, Copy)]
pub struct FixedByteBuffer<const N: usize> {
data: [u8; N],
}
impl<const N: usize> FixedByteBuffer<N> {
#[inline]
pub fn zeroed() -> Self {
Self {
data: [0u8; N],
}
}
#[inline]
pub fn from_array(arr: [u8; N]) -> Self {
Self {
data: arr,
}
}
#[inline]
pub fn as_array(&self) -> &[u8; N] {
&self.data
}
}
impl<const N: usize> ByteBuffer for FixedByteBuffer<N> {
#[inline]
fn len(&self) -> usize {
N
}
#[inline]
fn get(&self, at: usize) -> &u8 {
assert!(at < N, "index out of bounds: {at} >= {N}");
&self.data[at]
}
#[inline]
fn slice(&self) -> &[u8] {
&self.data
}
#[inline]
fn slice_start(&self, start: usize) -> &[u8] {
assert!(start <= N, "start out of bounds");
&self.data[start..]
}
#[inline]
fn slice_end(&self, end: usize) -> &[u8] {
assert!(end <= N, "end out of bounds");
&self.data[..end]
}
#[inline]
fn slice_both(&self, start: usize, end: usize) -> &[u8] {
assert!(start <= end && end <= N, "invalid slice bounds");
&self.data[start..end]
}
#[inline]
fn split(&self, divide: usize) -> (&[u8], &[u8]) {
assert!(divide <= N, "divide point out of bounds");
(&self.data[..divide], &self.data[divide..])
}
}
impl<const N: usize> AsRef<[u8]> for FixedByteBuffer<N> {
#[inline]
fn as_ref(&self) -> &[u8] {
&self.data
}
}
impl<const N: usize> From<[u8; N]> for FixedByteBuffer<N> {
#[inline]
fn from(arr: [u8; N]) -> Self {
Self {
data: arr,
}
}
}
impl<const N: usize> From<&[u8; N]> for FixedByteBuffer<N> {
#[inline]
fn from(arr: &[u8; N]) -> Self {
Self {
data: *arr,
}
}
}
impl<const N: usize> From<FixedByteBuffer<N>> for [u8; N] {
#[inline]
fn from(buf: FixedByteBuffer<N>) -> [u8; N] {
buf.data
}
}
impl<const N: usize> Default for FixedByteBuffer<N> {
#[inline]
fn default() -> Self {
Self::zeroed()
}
}
impl<const N: usize> PartialEq for FixedByteBuffer<N> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.data == other.data
}
}
impl<const N: usize> Eq for FixedByteBuffer<N> {}
impl<const N: usize> Hash for FixedByteBuffer<N> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.data.hash(state);
}
}
impl<const N: usize> Display for FixedByteBuffer<N> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
for byte in &self.data {
write!(f, "{byte:02x}")?;
}
Ok(())
}
}
impl<const N: usize> Debug for FixedByteBuffer<N> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("FixedByteBuffer").field("length", &N).field("data", &self.data).finish()
}
}