use super::Body;
use futures::future::poll_fn;
use shared_bytes::{SharedBytes, SharedStr};
use std::{
convert::Infallible,
fmt::Debug,
io::{self, Cursor},
iter,
pin::Pin,
sync::Arc,
};
pub(crate) trait DebugBody: Body + Debug + Unpin + Send + Sync + 'static {}
impl<R> DebugBody for R where R: Body + Debug + Unpin + Send + Sync + 'static {}
#[derive(Debug)]
pub struct BodyBox {
inner: Pin<Box<dyn DebugBody>>,
}
impl BodyBox {
pub fn new<B>(body: B) -> Self
where
B: Body + Debug + Unpin + Send + Sync + 'static,
{
Self {
inner: Box::pin(body),
}
}
pub fn empty() -> Self {
Self::new(())
}
pub async fn read_chunk(&mut self, buf: &mut [u8]) -> io::Result<usize> {
poll_fn(|cx| Body::poll_chunk(Pin::new(&mut *self.inner), cx, buf)).await
}
pub async fn chunk_size_hint(&mut self) -> io::Result<(usize, Option<usize>)> {
poll_fn(|cx| Body::poll_chunk_size_hint(Pin::new(&mut *self.inner), cx)).await
}
pub fn size_hint(&self) -> (usize, Option<usize>) {
Body::size_hint(&*self.inner)
}
pub async fn read_chunk_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
buf.reserve(self.chunk_size_hint().await?.0);
let start_length = buf.len();
let mut filled_bytes = start_length;
loop {
if buf.capacity() == filled_bytes {
buf.reserve(32)
}
buf.extend(iter::repeat(0).take(buf.capacity() - buf.len()));
match self.read_chunk(&mut buf[filled_bytes..]).await? {
0 => {
buf.truncate(filled_bytes);
return Ok(filled_bytes - start_length);
}
x => filled_bytes += x,
}
}
}
pub async fn read_chunk_vec(&mut self) -> io::Result<Vec<u8>> {
let mut buf = Vec::new();
self.read_chunk_to_end(&mut buf).await?;
Ok(buf)
}
pub fn from_bytes(bytes: Vec<u8>) -> Self {
Self::new(Cursor::new(bytes))
}
pub async fn read_vec(&mut self) -> io::Result<Vec<u8>> {
let mut buf = Vec::with_capacity(self.size_hint().0);
let read_bytes = self.read_chunk_to_end(&mut buf).await?;
let mut finished_chunk = read_bytes == 0;
loop {
let read_bytes = self.read_chunk_to_end(&mut buf).await?;
let read_nothing = read_bytes == 0;
if read_nothing && finished_chunk {
return Ok(buf);
}
finished_chunk = read_nothing;
}
}
pub async fn read_into_vec(mut self) -> io::Result<Vec<u8>> {
self.read_vec().await
}
pub fn from_string(string: String) -> Self {
Self::new(Cursor::new(string))
}
pub async fn read_string(&mut self) -> io::Result<String> {
let vec = self.read_vec().await?;
String::from_utf8(vec).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
}
pub async fn read_into_string(mut self) -> io::Result<String> {
self.read_string().await
}
}
impl Default for BodyBox {
fn default() -> Self {
Self::empty()
}
}
impl From<Vec<u8>> for BodyBox {
fn from(x: Vec<u8>) -> Self {
Self::from_bytes(x)
}
}
impl From<String> for BodyBox {
fn from(x: String) -> Self {
Self::from_string(x)
}
}
impl From<&'static [u8]> for BodyBox {
fn from(x: &'static [u8]) -> Self {
Self::new(Cursor::new(x))
}
}
impl From<&'static str> for BodyBox {
fn from(x: &'static str) -> Self {
Self::new(Cursor::new(x))
}
}
impl From<Arc<String>> for BodyBox {
fn from(x: Arc<String>) -> Self {
Self::new(Cursor::new(ArcAsRef(x)))
}
}
impl From<Arc<str>> for BodyBox {
fn from(x: Arc<str>) -> Self {
Self::new(Cursor::new(ArcAsRef(x)))
}
}
impl From<SharedStr> for BodyBox {
fn from(x: SharedStr) -> Self {
Self::new(Cursor::new(x))
}
}
impl From<Arc<Vec<u8>>> for BodyBox {
fn from(x: Arc<Vec<u8>>) -> Self {
Self::new(Cursor::new(ArcAsRef(x)))
}
}
impl From<Arc<[u8]>> for BodyBox {
fn from(x: Arc<[u8]>) -> Self {
Self::new(Cursor::new(ArcAsRef(x)))
}
}
impl From<SharedBytes> for BodyBox {
fn from(x: SharedBytes) -> Self {
Self::new(Cursor::new(x))
}
}
impl From<Infallible> for BodyBox {
fn from(_: Infallible) -> Self {
Self::empty()
}
}
impl<T, E> From<Result<T, E>> for BodyBox
where
T: Into<Self>,
E: Into<Self>,
{
fn from(x: Result<T, E>) -> Self {
match x {
Ok(t) => t.into(),
Err(e) => e.into(),
}
}
}
impl<T> From<Option<T>> for BodyBox
where
T: Into<Self>,
{
fn from(x: Option<T>) -> Self {
match x {
Some(t) => t.into(),
None => Self::empty(),
}
}
}
impl From<()> for BodyBox {
fn from(_: ()) -> Self {
Self::empty()
}
}
#[derive(Debug)]
struct ArcAsRef<T: ?Sized>(Arc<T>);
impl<T> AsRef<[u8]> for ArcAsRef<T>
where
T: AsRef<[u8]> + ?Sized,
{
fn as_ref(&self) -> &[u8] {
self.0.as_ref().as_ref()
}
}