use crate::io::{Error, Read, ReadResult, Result, Write};
pub struct Buffer<A> {
data: A,
len: usize,
}
impl<A> Buffer<A>
where
A: AsRef<[u8]>,
{
pub fn new(data: A) -> Self {
Self { data, len: 0 }
}
pub fn new_full(data: A) -> Self {
let len = data.as_ref().len();
Self { data, len }
}
pub fn new_with_len(data: A, len: usize) -> Self {
Self { data, len }
}
pub fn set_len(&mut self, len: usize) {
self.len = len;
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn cap(&self) -> usize {
self.data().len() - self.len
}
pub fn into_inner(self) -> A {
self.data
}
pub fn data(&self) -> &[u8] {
&self.data.as_ref()[..self.len]
}
pub fn get_ref(&self) -> &A {
&self.data
}
pub fn get_mut(&mut self) -> &mut A {
&mut self.data
}
}
impl<A> Buffer<A>
where
A: AsMut<[u8]>,
{
pub fn data_mut(&mut self) -> &mut [u8] {
&mut self.data.as_mut()[..self.len]
}
}
impl<A> Read for Buffer<A>
where
A: AsMut<[u8]>,
{
fn read(&mut self, buf: &mut [u8]) -> ReadResult {
if buf.is_empty() {
return Ok(Some(0));
}
let data = &mut self.data.as_mut()[..self.len];
if !data.is_empty() {
let cap = data.len().min(buf.len());
buf[..cap].copy_from_slice(&data[..cap]);
data.copy_within(cap.., 0);
self.len -= cap;
Ok(Some(cap))
} else {
Ok(None)
}
}
}
impl<A> Write for Buffer<A>
where
A: AsMut<[u8]>,
{
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let data = &mut self.data.as_mut()[self.len..];
if !data.is_empty() {
let cap = data.len().min(buf.len());
data[..cap].copy_from_slice(&buf[..cap]);
self.len += cap;
Ok(cap)
} else {
Err(Error::OutOfSpace)
}
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}