use std::io;
use std::pin::Pin;
use crate::data::data_stream::{DataStream, RawReader, RawStream};
use crate::data::peekable::Peekable;
use crate::data::transform::{InPlaceMap, Inspect, Transform, TransformBuf};
use crate::data::ByteUnit;
pub struct Data<'r> {
stream: Peekable<512, RawReader<'r>>,
transforms: Vec<Pin<Box<dyn Transform + Send + Sync + 'r>>>,
}
impl<'r> Data<'r> {
#[inline]
pub(crate) fn new(stream: Peekable<512, RawReader<'r>>) -> Self {
Self {
stream,
transforms: Vec::new(),
}
}
#[inline]
pub(crate) fn from<S: Into<RawStream<'r>>>(stream: S) -> Data<'r> {
Data::new(Peekable::new(RawReader::new(stream.into())))
}
#[inline]
pub(crate) fn local(data: Vec<u8>) -> Data<'r> {
Data::new(Peekable::with_buffer(
data,
true,
RawReader::new(RawStream::Empty),
))
}
#[inline(always)]
pub fn open(self, limit: ByteUnit) -> DataStream<'r> {
DataStream::new(self.transforms, self.stream, limit.into())
}
#[inline(always)]
pub async fn peek(&mut self, num: usize) -> &[u8] {
self.stream.peek(num).await
}
#[inline(always)]
pub fn peek_complete(&self) -> bool {
self.stream.complete
}
#[inline(always)]
pub fn chain_transform<T>(&mut self, transform: T) -> &mut Self
where
T: Transform + Send + Sync + 'static,
{
self.transforms.push(Box::pin(transform));
self
}
pub fn chain_inspect<F>(&mut self, f: F) -> &mut Self
where
F: FnMut(&[u8]) + Send + Sync + 'static,
{
self.chain_transform(Inspect(Box::new(f)))
}
pub fn chain_inplace_map<F>(&mut self, mut f: F) -> &mut Self
where
F: FnMut(&mut TransformBuf<'_, '_>) + Send + Sync + 'static,
{
self.chain_transform(InPlaceMap(Box::new(move |buf| {
f(buf);
Ok(())
})))
}
pub fn chain_try_inplace_map<F>(&mut self, f: F) -> &mut Self
where
F: FnMut(&mut TransformBuf<'_, '_>) -> io::Result<()> + Send + Sync + 'static,
{
self.chain_transform(InPlaceMap(Box::new(f)))
}
}