use std::mem;
use std::ops::Deref;
use std::ops::DerefMut;
use bytes::Bytes;
use futures::Future;
use crate::raw::*;
use crate::*;
pub type Reader = Box<dyn ReadDyn>;
pub trait Read: Unpin + Send + Sync {
fn open(
&self,
range: BytesRange,
) -> impl Future<Output = Result<(RpRead, Box<dyn ReadStreamDyn>)>> + MaybeSend;
fn read(&self, range: BytesRange)
-> impl Future<Output = Result<(RpRead, Buffer)>> + MaybeSend;
}
impl Read for () {
async fn open(&self, _: BytesRange) -> Result<(RpRead, Box<dyn ReadStreamDyn>)> {
Err(Error::new(
ErrorKind::Unsupported,
"output reader doesn't support open",
))
}
async fn read(&self, _: BytesRange) -> Result<(RpRead, Buffer)> {
Err(Error::new(
ErrorKind::Unsupported,
"output reader doesn't support read",
))
}
}
pub trait ReadDyn: Unpin + Send + Sync {
fn open_dyn(
&self,
range: BytesRange,
) -> BoxedFuture<'_, Result<(RpRead, Box<dyn ReadStreamDyn>)>>;
fn read_dyn(&self, range: BytesRange) -> BoxedFuture<'_, Result<(RpRead, Buffer)>>;
}
impl<T: Read + ?Sized> ReadDyn for T {
fn open_dyn(
&self,
range: BytesRange,
) -> BoxedFuture<'_, Result<(RpRead, Box<dyn ReadStreamDyn>)>> {
Box::pin(self.open(range))
}
fn read_dyn(&self, range: BytesRange) -> BoxedFuture<'_, Result<(RpRead, Buffer)>> {
Box::pin(self.read(range))
}
}
impl<T: ReadDyn + ?Sized> Read for Box<T> {
async fn open(&self, range: BytesRange) -> Result<(RpRead, Box<dyn ReadStreamDyn>)> {
self.deref().open_dyn(range).await
}
async fn read(&self, range: BytesRange) -> Result<(RpRead, Buffer)> {
self.deref().read_dyn(range).await
}
}
pub trait ReadStream: Unpin + Send + Sync {
fn read(&mut self) -> impl Future<Output = Result<Buffer>> + MaybeSend;
fn read_all(&mut self) -> impl Future<Output = Result<Buffer>> + MaybeSend {
async {
let mut bufs = vec![];
loop {
match self.read().await {
Ok(buf) if buf.is_empty() => break,
Ok(buf) => bufs.push(buf),
Err(err) => return Err(err),
}
}
Ok(bufs.into_iter().flatten().collect())
}
}
}
impl ReadStream for () {
async fn read(&mut self) -> Result<Buffer> {
Err(Error::new(
ErrorKind::Unsupported,
"output reader doesn't support read",
))
}
}
impl ReadStream for Bytes {
async fn read(&mut self) -> Result<Buffer> {
Ok(Buffer::from(self.split_off(0)))
}
}
impl ReadStream for Buffer {
async fn read(&mut self) -> Result<Buffer> {
Ok(mem::take(self))
}
}
pub trait ReadStreamDyn: Unpin + Send + Sync {
fn read_dyn(&mut self) -> BoxedFuture<'_, Result<Buffer>>;
fn read_all_dyn(&mut self) -> BoxedFuture<'_, Result<Buffer>>;
}
impl<T: ReadStream + ?Sized> ReadStreamDyn for T {
fn read_dyn(&mut self) -> BoxedFuture<'_, Result<Buffer>> {
Box::pin(self.read())
}
fn read_all_dyn(&mut self) -> BoxedFuture<'_, Result<Buffer>> {
Box::pin(self.read_all())
}
}
impl<T: ReadStreamDyn + ?Sized> ReadStream for Box<T> {
async fn read(&mut self) -> Result<Buffer> {
self.deref_mut().read_dyn().await
}
async fn read_all(&mut self) -> Result<Buffer> {
self.deref_mut().read_all_dyn().await
}
}