use std::ops::RangeBounds;
use super::types::BlockSignature;
pub trait EjectBuf {
fn eject(self) -> Vec<u8>;
}
#[derive(Debug)]
pub struct FullSliceBuf {
buf: Vec<u8>,
}
impl FullSliceBuf {
pub fn new(buf: Vec<u8>) -> Self {
FullSliceBuf { buf }
}
pub fn splice<R, I>(&mut self, range: R, replace_with: I)
where
R: RangeBounds<usize>,
I: IntoIterator<Item = u8>,
{
self.buf.splice(range, replace_with);
}
}
impl EjectBuf for FullSliceBuf {
fn eject(mut self) -> Vec<u8> {
self.buf.clear();
self.buf
}
}
impl AsRef<[u8]> for FullSliceBuf {
fn as_ref(&self) -> &[u8] {
self.buf.as_ref()
}
}
impl AsMut<[u8]> for FullSliceBuf {
fn as_mut(&mut self) -> &mut [u8] {
self.buf.as_mut()
}
}
#[derive(Debug)]
pub struct PartialSliceBuf {
buf: Vec<u8>,
first_block: Option<BlockSignature>,
last_block: Option<BlockSignature>,
}
impl PartialSliceBuf {
pub fn new(
buf: Vec<u8>,
first_block: Option<BlockSignature>,
last_block: Option<BlockSignature>,
) -> Self {
PartialSliceBuf {
buf,
first_block,
last_block,
}
}
pub fn first_block_signature(&self) -> Option<&BlockSignature> {
self.first_block.as_ref()
}
pub fn last_block_signature(&self) -> Option<&BlockSignature> {
self.last_block.as_ref()
}
pub fn first_block_data(&self) -> Option<&[u8]> {
match &self.first_block {
Some(BlockSignature::Data { len, .. }) => Some(
self.buf
.get(0..*len)
.expect("Partial slice buffer unexpectedly missing the first block."),
),
_ => None,
}
}
pub fn last_block_data(&self) -> Option<&[u8]> {
let first_data_len = match &self.first_block {
Some(BlockSignature::Data { len, .. }) => *len,
_ => 0,
};
match &self.last_block {
Some(BlockSignature::Data { len, .. }) => Some(
self.buf
.get(first_data_len..(first_data_len + *len))
.expect("Partial slice buffer unexpectedly missing the last block."),
),
_ => None,
}
}
}
impl EjectBuf for PartialSliceBuf {
fn eject(mut self) -> Vec<u8> {
self.buf.clear();
self.buf
}
}
pub enum SliceBuf {
Full(FullSliceBuf),
Partial(PartialSliceBuf),
}
impl EjectBuf for SliceBuf {
fn eject(self) -> Vec<u8> {
match self {
SliceBuf::Full(b) => b.eject(),
SliceBuf::Partial(b) => b.eject(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SliceReadMode {
Full,
Partial,
}