use either::Either;
use std::{iter::FromIterator, sync::Arc, usize};
use crate::{trusted_len::TrustedLen, types::NativeType};
use super::bytes::Bytes;
#[derive(Clone, PartialEq)]
pub struct Buffer<T: NativeType> {
data: Arc<Bytes<T>>,
offset: usize,
length: usize,
}
impl<T: NativeType> std::fmt::Debug for Buffer<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&**self, f)
}
}
impl<T: NativeType> Default for Buffer<T> {
#[inline]
fn default() -> Self {
Vec::new().into()
}
}
impl<T: NativeType> Buffer<T> {
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn new_zeroed(length: usize) -> Self {
vec![T::default(); length].into()
}
#[inline]
pub fn from_slice<R: AsRef<[T]>>(data: R) -> Self {
data.as_ref().to_vec().into()
}
pub(crate) fn from_bytes(bytes: Bytes<T>) -> Self {
let length = bytes.len();
Buffer {
data: Arc::new(bytes),
offset: 0,
length,
}
}
#[inline]
pub fn len(&self) -> usize {
self.length
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn as_slice(&self) -> &[T] {
debug_assert!(self.offset + self.length <= self.data.len());
unsafe {
self.data
.get_unchecked(self.offset..self.offset + self.length)
}
}
#[inline]
pub fn slice(self, offset: usize, length: usize) -> Self {
assert!(
offset + length <= self.len(),
"the offset of the new Buffer cannot exceed the existing length"
);
unsafe { self.slice_unchecked(offset, length) }
}
#[inline]
pub unsafe fn slice_unchecked(mut self, offset: usize, length: usize) -> Self {
self.offset += offset;
self.length = length;
self
}
#[inline]
pub(crate) fn as_ptr(&self) -> std::ptr::NonNull<T> {
self.data.ptr()
}
#[inline]
pub fn offset(&self) -> usize {
self.offset
}
pub fn into_mut(mut self) -> Either<Self, Vec<T>> {
if self.offset != 0 {
Either::Left(self)
} else {
match Arc::get_mut(&mut self.data).and_then(|b| b.get_vec()) {
Some(v) => {
let data = std::mem::take(v);
Either::Right(data)
}
None => Either::Left(self),
}
}
}
}
impl<T: NativeType> Buffer<T> {
#[inline]
pub fn from_trusted_len_iter<I: TrustedLen<Item = T>>(iterator: I) -> Self {
iterator.collect::<Vec<_>>().into()
}
#[inline]
pub fn try_from_trusted_len_iter<E, I: TrustedLen<Item = std::result::Result<T, E>>>(
iterator: I,
) -> std::result::Result<Self, E> {
Ok(iterator.collect::<std::result::Result<Vec<_>, E>>()?.into())
}
#[inline]
pub unsafe fn from_trusted_len_iter_unchecked<I: Iterator<Item = T>>(iterator: I) -> Self {
iterator.collect::<Vec<_>>().into()
}
#[inline]
pub unsafe fn try_from_trusted_len_iter_unchecked<
E,
I: Iterator<Item = std::result::Result<T, E>>,
>(
iterator: I,
) -> std::result::Result<Self, E> {
Ok(iterator.collect::<std::result::Result<Vec<_>, E>>()?.into())
}
}
impl<T: NativeType> From<Vec<T>> for Buffer<T> {
#[inline]
fn from(p: Vec<T>) -> Self {
let bytes: Bytes<T> = p.into();
Self {
offset: 0,
length: bytes.len(),
data: Arc::new(bytes),
}
}
}
impl<T: NativeType> std::ops::Deref for Buffer<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &[T] {
self.as_slice()
}
}
impl<T: NativeType> FromIterator<T> for Buffer<T> {
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Vec::from_iter(iter).into()
}
}