summaryrefslogtreecommitdiffstats
path: root/third_party/rust/hyper/src/server/accept.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/hyper/src/server/accept.rs')
-rw-r--r--third_party/rust/hyper/src/server/accept.rs111
1 files changed, 111 insertions, 0 deletions
diff --git a/third_party/rust/hyper/src/server/accept.rs b/third_party/rust/hyper/src/server/accept.rs
new file mode 100644
index 0000000000..4b7a1487dd
--- /dev/null
+++ b/third_party/rust/hyper/src/server/accept.rs
@@ -0,0 +1,111 @@
+//! The `Accept` trait and supporting types.
+//!
+//! This module contains:
+//!
+//! - The [`Accept`](Accept) trait used to asynchronously accept incoming
+//! connections.
+//! - Utilities like `poll_fn` to ease creating a custom `Accept`.
+
+#[cfg(feature = "stream")]
+use futures_core::Stream;
+#[cfg(feature = "stream")]
+use pin_project_lite::pin_project;
+
+use crate::common::{
+ task::{self, Poll},
+ Pin,
+};
+
+/// Asynchronously accept incoming connections.
+pub trait Accept {
+ /// The connection type that can be accepted.
+ type Conn;
+ /// The error type that can occur when accepting a connection.
+ type Error;
+
+ /// Poll to accept the next connection.
+ fn poll_accept(
+ self: Pin<&mut Self>,
+ cx: &mut task::Context<'_>,
+ ) -> Poll<Option<Result<Self::Conn, Self::Error>>>;
+}
+
+/// Create an `Accept` with a polling function.
+///
+/// # Example
+///
+/// ```
+/// use std::task::Poll;
+/// use hyper::server::{accept, Server};
+///
+/// # let mock_conn = ();
+/// // If we created some mocked connection...
+/// let mut conn = Some(mock_conn);
+///
+/// // And accept just the mocked conn once...
+/// let once = accept::poll_fn(move |cx| {
+/// Poll::Ready(conn.take().map(Ok::<_, ()>))
+/// });
+///
+/// let builder = Server::builder(once);
+/// ```
+pub fn poll_fn<F, IO, E>(func: F) -> impl Accept<Conn = IO, Error = E>
+where
+ F: FnMut(&mut task::Context<'_>) -> Poll<Option<Result<IO, E>>>,
+{
+ struct PollFn<F>(F);
+
+ // The closure `F` is never pinned
+ impl<F> Unpin for PollFn<F> {}
+
+ impl<F, IO, E> Accept for PollFn<F>
+ where
+ F: FnMut(&mut task::Context<'_>) -> Poll<Option<Result<IO, E>>>,
+ {
+ type Conn = IO;
+ type Error = E;
+ fn poll_accept(
+ self: Pin<&mut Self>,
+ cx: &mut task::Context<'_>,
+ ) -> Poll<Option<Result<Self::Conn, Self::Error>>> {
+ (self.get_mut().0)(cx)
+ }
+ }
+
+ PollFn(func)
+}
+
+/// Adapt a `Stream` of incoming connections into an `Accept`.
+///
+/// # Optional
+///
+/// This function requires enabling the `stream` feature in your
+/// `Cargo.toml`.
+#[cfg(feature = "stream")]
+pub fn from_stream<S, IO, E>(stream: S) -> impl Accept<Conn = IO, Error = E>
+where
+ S: Stream<Item = Result<IO, E>>,
+{
+ pin_project! {
+ struct FromStream<S> {
+ #[pin]
+ stream: S,
+ }
+ }
+
+ impl<S, IO, E> Accept for FromStream<S>
+ where
+ S: Stream<Item = Result<IO, E>>,
+ {
+ type Conn = IO;
+ type Error = E;
+ fn poll_accept(
+ self: Pin<&mut Self>,
+ cx: &mut task::Context<'_>,
+ ) -> Poll<Option<Result<Self::Conn, Self::Error>>> {
+ self.project().stream.poll_next(cx)
+ }
+ }
+
+ FromStream { stream }
+}