summaryrefslogtreecommitdiffstats
path: root/third_party/rust/http-body/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/http-body/src/lib.rs242
1 files changed, 242 insertions, 0 deletions
diff --git a/third_party/rust/http-body/src/lib.rs b/third_party/rust/http-body/src/lib.rs
new file mode 100644
index 0000000000..0d0e061d98
--- /dev/null
+++ b/third_party/rust/http-body/src/lib.rs
@@ -0,0 +1,242 @@
+#![doc(html_root_url = "https://docs.rs/http-body/0.3.1")]
+#![deny(missing_debug_implementations, missing_docs, unreachable_pub)]
+#![cfg_attr(test, deny(warnings))]
+
+//! Asynchronous HTTP request or response body.
+//!
+//! See [`Body`] for more details.
+//!
+//! [`Body`]: trait.Body.html
+
+mod next;
+mod size_hint;
+
+pub use self::next::{Data, Trailers};
+pub use self::size_hint::SizeHint;
+
+use bytes::Buf;
+use http::HeaderMap;
+use std::ops;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+/// Trait representing a streaming body of a Request or Response.
+///
+/// Data is streamed via the `poll_data` function, which asynchronously yields `T: Buf` values. The
+/// `size_hint` function provides insight into the total number of bytes that will be streamed.
+///
+/// The `poll_trailers` function returns an optional set of trailers used to finalize the request /
+/// response exchange. This is mostly used when using the HTTP/2.0 protocol.
+///
+pub trait Body {
+ /// Values yielded by the `Body`.
+ type Data: Buf;
+
+ /// The error type this `Body` might generate.
+ type Error;
+
+ /// Attempt to pull out the next data buffer of this stream.
+ fn poll_data(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>>;
+
+ /// Poll for an optional **single** `HeaderMap` of trailers.
+ ///
+ /// This function should only be called once `poll_data` returns `None`.
+ fn poll_trailers(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>>;
+
+ /// Returns `true` when the end of stream has been reached.
+ ///
+ /// An end of stream means that both `poll_data` and `poll_trailers` will
+ /// return `None`.
+ ///
+ /// A return value of `false` **does not** guarantee that a value will be
+ /// returned from `poll_stream` or `poll_trailers`.
+ fn is_end_stream(&self) -> bool {
+ false
+ }
+
+ /// Returns the bounds on the remaining length of the stream.
+ ///
+ /// When the **exact** remaining length of the stream is known, the upper bound will be set and
+ /// will equal the lower bound.
+ fn size_hint(&self) -> SizeHint {
+ SizeHint::default()
+ }
+
+ /// Returns future that resolves to next data chunk, if any.
+ fn data(&mut self) -> Data<'_, Self>
+ where
+ Self: Unpin + Sized,
+ {
+ Data(self)
+ }
+
+ /// Returns future that resolves to trailers, if any.
+ fn trailers(&mut self) -> Trailers<'_, Self>
+ where
+ Self: Unpin + Sized,
+ {
+ Trailers(self)
+ }
+}
+
+impl<T: Body + Unpin + ?Sized> Body for &mut T {
+ type Data = T::Data;
+ type Error = T::Error;
+
+ fn poll_data(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ Pin::new(&mut **self).poll_data(cx)
+ }
+
+ fn poll_trailers(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ Pin::new(&mut **self).poll_trailers(cx)
+ }
+
+ fn is_end_stream(&self) -> bool {
+ Pin::new(&**self).is_end_stream()
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ Pin::new(&**self).size_hint()
+ }
+}
+
+impl<P> Body for Pin<P>
+where
+ P: Unpin + ops::DerefMut,
+ P::Target: Body,
+{
+ type Data = <<P as ops::Deref>::Target as Body>::Data;
+ type Error = <<P as ops::Deref>::Target as Body>::Error;
+
+ fn poll_data(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ Pin::get_mut(self).as_mut().poll_data(cx)
+ }
+
+ fn poll_trailers(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ Pin::get_mut(self).as_mut().poll_trailers(cx)
+ }
+
+ fn is_end_stream(&self) -> bool {
+ self.as_ref().is_end_stream()
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ self.as_ref().size_hint()
+ }
+}
+
+impl<T: Body + Unpin + ?Sized> Body for Box<T> {
+ type Data = T::Data;
+ type Error = T::Error;
+
+ fn poll_data(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ Pin::new(&mut **self).poll_data(cx)
+ }
+
+ fn poll_trailers(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ Pin::new(&mut **self).poll_trailers(cx)
+ }
+
+ fn is_end_stream(&self) -> bool {
+ self.as_ref().is_end_stream()
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ self.as_ref().size_hint()
+ }
+}
+
+impl<B: Body> Body for http::Request<B> {
+ type Data = B::Data;
+ type Error = B::Error;
+
+ fn poll_data(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ unsafe {
+ self.map_unchecked_mut(http::Request::body_mut)
+ .poll_data(cx)
+ }
+ }
+
+ fn poll_trailers(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ unsafe {
+ self.map_unchecked_mut(http::Request::body_mut)
+ .poll_trailers(cx)
+ }
+ }
+
+ fn is_end_stream(&self) -> bool {
+ self.body().is_end_stream()
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ self.body().size_hint()
+ }
+}
+
+impl<B: Body> Body for http::Response<B> {
+ type Data = B::Data;
+ type Error = B::Error;
+
+ fn poll_data(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ unsafe {
+ self.map_unchecked_mut(http::Response::body_mut)
+ .poll_data(cx)
+ }
+ }
+
+ fn poll_trailers(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ unsafe {
+ self.map_unchecked_mut(http::Response::body_mut)
+ .poll_trailers(cx)
+ }
+ }
+
+ fn is_end_stream(&self) -> bool {
+ self.body().is_end_stream()
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ self.body().size_hint()
+ }
+}
+
+#[cfg(test)]
+fn _assert_bounds() {
+ fn can_be_trait_object(_: &dyn Body<Data = std::io::Cursor<Vec<u8>>, Error = std::io::Error>) {}
+}