use crate::{Body, Headers, body::BodyType};
use futures_lite::AsyncRead;
use std::{io, pin::Pin, task::Poll};
#[derive(Debug)]
pub(crate) struct H2Body {
body: BodyType,
}
impl H2Body {
pub(crate) fn new(body: Body) -> Self {
Self { body: body.0 }
}
pub(crate) fn trailers(&mut self) -> Option<Headers> {
match &mut self.body {
BodyType::Streaming {
async_read, done, ..
} if *done => async_read.get_mut().as_mut().trailers(),
_ => None,
}
}
}
impl AsyncRead for H2Body {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
let this = self.get_mut();
match &mut this.body {
BodyType::Empty => Poll::Ready(Ok(0)),
BodyType::Static { content, cursor } => {
let remaining = content.len() - *cursor;
if remaining == 0 {
return Poll::Ready(Ok(0));
}
let bytes = remaining.min(buf.len());
buf[..bytes].copy_from_slice(&content[*cursor..*cursor + bytes]);
*cursor += bytes;
Poll::Ready(Ok(bytes))
}
BodyType::Streaming {
async_read,
done,
progress,
..
} => {
if *done {
return Poll::Ready(Ok(0));
}
let bytes = futures_lite::ready!(async_read.get_mut().as_mut().poll_read(cx, buf))?;
if bytes == 0 {
*done = true;
} else {
*progress += bytes as u64;
}
Poll::Ready(Ok(bytes))
}
}
}
}