use crate::{IoBuf, IoBufMut};
use std::ops::{Bound, Range, RangeBounds};
#[derive(Debug, Clone)]
pub struct BufferSlice<B> {
buffer: B,
range: Range<usize>,
}
impl<B: IoBuf> BufferSlice<B> {
pub(crate) fn new(buffer: B, range: impl RangeBounds<usize>) -> Self {
let start = match range.start_bound() {
Bound::Included(&start) => start,
Bound::Excluded(&start) => start.checked_add(1).expect("buffer range start overflow"),
Bound::Unbounded => 0,
};
let end = match range.end_bound() {
Bound::Included(&end) => end.checked_add(1).expect("buffer range end overflow"),
Bound::Excluded(&end) => end,
Bound::Unbounded => buffer.as_ref().len(),
};
assert!(
start <= end && end <= buffer.as_ref().len(),
"buffer range out of bounds"
);
Self {
buffer,
range: start..end,
}
}
pub fn into_inner(self) -> B {
self.buffer
}
}
impl<B: IoBuf> AsRef<[u8]> for BufferSlice<B> {
fn as_ref(&self) -> &[u8] {
&self.buffer.as_ref()[self.range.clone()]
}
}
impl<B: IoBufMut> AsMut<[u8]> for BufferSlice<B> {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.buffer.as_mut()[self.range.clone()]
}
}
unsafe impl<B: IoBuf> IoBuf for BufferSlice<B> {}
unsafe impl<B: IoBufMut> IoBufMut for BufferSlice<B> {}