use std::ops::RangeBounds;
use bytes::BufMut;
use super::BufferIterator;
use super::StdBytesIterator;
use super::StdReader;
use crate::Reader as AsyncReader;
use crate::*;
#[derive(Clone)]
pub struct Reader {
handle: tokio::runtime::Handle,
inner: Option<AsyncReader>,
}
impl Reader {
pub(crate) fn new(handle: tokio::runtime::Handle, inner: AsyncReader) -> Self {
Reader {
handle,
inner: Some(inner),
}
}
pub fn read(&self, range: impl RangeBounds<u64>) -> Result<Buffer> {
let inner = self
.inner
.as_ref()
.ok_or_else(|| Error::new(ErrorKind::Unexpected, "reader has been dropped"))?;
self.handle.block_on(inner.read(range))
}
pub fn read_into(&self, buf: &mut impl BufMut, range: impl RangeBounds<u64>) -> Result<usize> {
let inner = self
.inner
.as_ref()
.ok_or_else(|| Error::new(ErrorKind::Unexpected, "reader has been dropped"))?;
self.handle.block_on(inner.read_into(buf, range))
}
pub fn into_iterator(mut self, range: impl RangeBounds<u64>) -> Result<BufferIterator> {
let inner = self
.inner
.take()
.ok_or_else(|| Error::new(ErrorKind::Unexpected, "reader has been dropped"))?;
let iter = self.handle.block_on(inner.into_stream(range))?;
Ok(BufferIterator::new(self.handle.clone(), iter))
}
#[inline]
pub fn into_std_read(mut self, range: impl RangeBounds<u64>) -> Result<StdReader> {
let inner = self
.inner
.take()
.ok_or_else(|| Error::new(ErrorKind::Unexpected, "reader has been dropped"))?;
let r = self.handle.block_on(inner.into_futures_async_read(range))?;
Ok(StdReader::new(self.handle.clone(), r))
}
#[inline]
pub fn into_bytes_iterator(mut self, range: impl RangeBounds<u64>) -> Result<StdBytesIterator> {
let inner = self
.inner
.take()
.ok_or_else(|| Error::new(ErrorKind::Unexpected, "reader has been dropped"))?;
let iter = self.handle.block_on(inner.into_bytes_stream(range))?;
Ok(StdBytesIterator::new(self.handle.clone(), iter))
}
}
impl Drop for Reader {
fn drop(&mut self) {
if let Some(v) = self.inner.take() {
self.handle.block_on(async move { drop(v) });
}
}
}