use bytes::Bytes;
use std::{
fmt::{Debug, Display, Formatter, Result as FmtResult},
ops::Index,
};
#[derive(Clone, Debug)]
pub struct ByteBufferPtr {
data: Bytes,
}
impl ByteBufferPtr {
pub fn new(v: Vec<u8>) -> Self {
Self { data: v.into() }
}
#[inline]
pub fn data(&self) -> &[u8] {
&self.data
}
#[inline]
pub fn len(&self) -> usize {
self.data.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn all(&self) -> Self {
self.clone()
}
pub fn start_from(&self, start: usize) -> Self {
Self {
data: self.data.slice(start..),
}
}
pub fn range(&self, start: usize, len: usize) -> Self {
Self {
data: self.data.slice(start..start + len),
}
}
}
impl Index<usize> for ByteBufferPtr {
type Output = u8;
fn index(&self, index: usize) -> &u8 {
&self.data[index]
}
}
impl Display for ByteBufferPtr {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "{:?}", self.data)
}
}
impl AsRef<[u8]> for ByteBufferPtr {
#[inline]
fn as_ref(&self) -> &[u8] {
&self.data
}
}
impl From<Vec<u8>> for ByteBufferPtr {
fn from(data: Vec<u8>) -> Self {
Self { data: data.into() }
}
}
impl From<Bytes> for ByteBufferPtr {
fn from(data: Bytes) -> Self {
Self { data }
}
}
impl From<ByteBufferPtr> for Bytes {
fn from(value: ByteBufferPtr) -> Self {
value.data
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_byte_ptr() {
let values = (0..50).collect();
let ptr = ByteBufferPtr::new(values);
assert_eq!(ptr.len(), 50);
assert_eq!(ptr[40], 40);
let ptr2 = ptr.all();
assert_eq!(ptr2.len(), 50);
assert_eq!(ptr2[40], 40);
let ptr3 = ptr.start_from(20);
assert_eq!(ptr3.len(), 30);
assert_eq!(ptr3[0], 20);
let ptr4 = ptr3.range(10, 10);
assert_eq!(ptr4.len(), 10);
assert_eq!(ptr4[0], 30);
let expected: Vec<u8> = (30..40).collect();
assert_eq!(ptr4.as_ref(), expected.as_slice());
}
}