use alloc::boxed::Box;
use core::{ops, slice};
#[derive(Debug)]
pub enum SmallByteSlice {
Small {
len: u8,
bytes: [u8; Self::MAX_INLINE_SIZE],
},
Big(Box<[u8]>),
}
impl Default for SmallByteSlice {
fn default() -> Self {
Self::Small {
len: 0,
bytes: [0x00; Self::MAX_INLINE_SIZE],
}
}
}
impl SmallByteSlice {
const MAX_INLINE_SIZE: usize = 22;
#[inline]
pub fn as_slice(&self) -> &[u8] {
match self {
SmallByteSlice::Small { len, bytes } => &bytes[..usize::from(*len)],
SmallByteSlice::Big(bytes) => &bytes[..],
}
}
}
impl<I> ops::Index<I> for SmallByteSlice
where
I: slice::SliceIndex<[u8]>,
{
type Output = <I as slice::SliceIndex<[u8]>>::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
self.as_slice().index(index)
}
}
impl<'a> From<&'a [u8]> for SmallByteSlice {
fn from(bytes: &'a [u8]) -> Self {
if bytes.len() <= Self::MAX_INLINE_SIZE {
let len = bytes.len() as u8;
let mut buffer = [0x00_u8; Self::MAX_INLINE_SIZE];
buffer[..usize::from(len)].copy_from_slice(bytes);
return Self::Small { len, bytes: buffer };
}
Self::Big(bytes.into())
}
}