use bytes::Bytes;
#[derive(Debug, Clone)]
pub struct ZeroCopyBuffer {
data: Bytes,
}
impl ZeroCopyBuffer {
pub fn new(data: Bytes) -> Self {
Self { data }
}
pub fn from_vec(vec: Vec<u8>) -> Self {
Self {
data: Bytes::from(vec),
}
}
pub fn from_static(bytes: &'static [u8]) -> Self {
Self {
data: Bytes::from_static(bytes),
}
}
pub fn as_slice(&self) -> &[u8] {
&self.data
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn slice(&self, range: std::ops::Range<usize>) -> Self {
Self {
data: self.data.slice(range),
}
}
pub fn into_bytes(self) -> Bytes {
self.data
}
pub fn bytes(&self) -> &Bytes {
&self.data
}
pub fn split_at(&self, at: usize) -> (Self, Self) {
let left = self.data.slice(0..at);
let right = self.data.slice(at..);
(Self { data: left }, Self { data: right })
}
pub fn split_to(&self, at: usize) -> Self {
Self {
data: self.data.slice(0..at),
}
}
pub fn split_from(&self, at: usize) -> Self {
Self {
data: self.data.slice(at..),
}
}
}
impl From<Vec<u8>> for ZeroCopyBuffer {
fn from(vec: Vec<u8>) -> Self {
Self::from_vec(vec)
}
}
impl From<Bytes> for ZeroCopyBuffer {
fn from(bytes: Bytes) -> Self {
Self::new(bytes)
}
}
impl From<&'static [u8]> for ZeroCopyBuffer {
fn from(bytes: &'static [u8]) -> Self {
Self::from_static(bytes)
}
}
impl AsRef<[u8]> for ZeroCopyBuffer {
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_zero_copy_buffer_basic() {
let data = vec![1, 2, 3, 4, 5];
let buf = ZeroCopyBuffer::from_vec(data);
assert_eq!(buf.len(), 5);
assert!(!buf.is_empty());
assert_eq!(buf.as_slice(), &[1, 2, 3, 4, 5]);
}
#[test]
fn test_zero_copy_slice() {
let buf = ZeroCopyBuffer::from_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
let slice = buf.slice(2..7);
assert_eq!(slice.len(), 5);
assert_eq!(slice.as_slice(), &[2, 3, 4, 5, 6]);
}
#[test]
fn test_zero_copy_split_at() {
let buf = ZeroCopyBuffer::from_vec(vec![1, 2, 3, 4, 5]);
let (left, right) = buf.split_at(3);
assert_eq!(left.as_slice(), &[1, 2, 3]);
assert_eq!(right.as_slice(), &[4, 5]);
}
#[test]
fn test_zero_copy_split_to() {
let buf = ZeroCopyBuffer::from_vec(vec![1, 2, 3, 4, 5]);
let first = buf.split_to(3);
assert_eq!(first.as_slice(), &[1, 2, 3]);
}
#[test]
fn test_zero_copy_split_from() {
let buf = ZeroCopyBuffer::from_vec(vec![1, 2, 3, 4, 5]);
let last = buf.split_from(3);
assert_eq!(last.as_slice(), &[4, 5]);
}
#[test]
fn test_zero_copy_from_static() {
let buf = ZeroCopyBuffer::from_static(b"hello world");
assert_eq!(buf.len(), 11);
assert_eq!(buf.as_slice(), b"hello world");
}
#[test]
fn test_zero_copy_empty() {
let buf = ZeroCopyBuffer::from_vec(vec![]);
assert_eq!(buf.len(), 0);
assert!(buf.is_empty());
}
}