summaryrefslogtreecommitdiff
path: root/vendor/tower/src/make
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
committermo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
commit8cdfa445d6629ffef4cb84967ff7017654045bc2 (patch)
tree22f0b0907c024c78d26a731e2e1f5219407d8102 /vendor/tower/src/make
parent4351c74c7c5f97156bc94d3a8549b9940ac80e3f (diff)
chore: add vendor directory
Diffstat (limited to 'vendor/tower/src/make')
-rw-r--r--vendor/tower/src/make/make_connection.rs47
-rw-r--r--vendor/tower/src/make/make_service.rs251
-rw-r--r--vendor/tower/src/make/make_service/shared.rs146
-rw-r--r--vendor/tower/src/make/mod.rs14
4 files changed, 458 insertions, 0 deletions
diff --git a/vendor/tower/src/make/make_connection.rs b/vendor/tower/src/make/make_connection.rs
new file mode 100644
index 00000000..9566cc68
--- /dev/null
+++ b/vendor/tower/src/make/make_connection.rs
@@ -0,0 +1,47 @@
+use crate::sealed::Sealed;
+use std::future::Future;
+use std::task::{Context, Poll};
+use tokio::io::{AsyncRead, AsyncWrite};
+use tower_service::Service;
+
+/// The [`MakeConnection`] trait is used to create transports.
+///
+/// The goal of this service is to allow composable methods for creating
+/// `AsyncRead + AsyncWrite` transports. This could mean creating a TLS
+/// based connection or using some other method to authenticate the connection.
+pub trait MakeConnection<Target>: Sealed<(Target,)> {
+ /// The transport provided by this service
+ type Connection: AsyncRead + AsyncWrite;
+
+ /// Errors produced by the connecting service
+ type Error;
+
+ /// The future that eventually produces the transport
+ type Future: Future<Output = Result<Self::Connection, Self::Error>>;
+
+ /// Returns `Poll::Ready(Ok(()))` when it is able to make more connections.
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
+
+ /// Connect and return a transport asynchronously
+ fn make_connection(&mut self, target: Target) -> Self::Future;
+}
+
+impl<S, Target> Sealed<(Target,)> for S where S: Service<Target> {}
+
+impl<C, Target> MakeConnection<Target> for C
+where
+ C: Service<Target>,
+ C::Response: AsyncRead + AsyncWrite,
+{
+ type Connection = C::Response;
+ type Error = C::Error;
+ type Future = C::Future;
+
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ Service::poll_ready(self, cx)
+ }
+
+ fn make_connection(&mut self, target: Target) -> Self::Future {
+ Service::call(self, target)
+ }
+}
diff --git a/vendor/tower/src/make/make_service.rs b/vendor/tower/src/make/make_service.rs
new file mode 100644
index 00000000..aa519d68
--- /dev/null
+++ b/vendor/tower/src/make/make_service.rs
@@ -0,0 +1,251 @@
+//! Contains [`MakeService`] which is a trait alias for a [`Service`] of [`Service`]s.
+
+use crate::sealed::Sealed;
+use std::fmt;
+use std::future::Future;
+use std::marker::PhantomData;
+use std::task::{Context, Poll};
+use tower_service::Service;
+
+pub(crate) mod shared;
+
+/// Creates new [`Service`] values.
+///
+/// Acts as a service factory. This is useful for cases where new [`Service`]
+/// values must be produced. One case is a TCP server listener. The listener
+/// accepts new TCP streams, obtains a new [`Service`] value using the
+/// [`MakeService`] trait, and uses that new [`Service`] value to process inbound
+/// requests on that new TCP stream.
+///
+/// This is essentially a trait alias for a [`Service`] of [`Service`]s.
+pub trait MakeService<Target, Request>: Sealed<(Target, Request)> {
+ /// Responses given by the service
+ type Response;
+
+ /// Errors produced by the service
+ type Error;
+
+ /// The [`Service`] value created by this factory
+ type Service: Service<Request, Response = Self::Response, Error = Self::Error>;
+
+ /// Errors produced while building a service.
+ type MakeError;
+
+ /// The future of the [`Service`] instance.
+ type Future: Future<Output = Result<Self::Service, Self::MakeError>>;
+
+ /// Returns [`Poll::Ready`] when the factory is able to create more services.
+ ///
+ /// If the service is at capacity, then [`Poll::Pending`] is returned and the task
+ /// is notified when the service becomes ready again. This function is
+ /// expected to be called while on a task.
+ ///
+ /// [`Poll::Ready`]: std::task::Poll::Ready
+ /// [`Poll::Pending`]: std::task::Poll::Pending
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::MakeError>>;
+
+ /// Create and return a new service value asynchronously.
+ fn make_service(&mut self, target: Target) -> Self::Future;
+
+ /// Consume this [`MakeService`] and convert it into a [`Service`].
+ ///
+ /// # Example
+ /// ```
+ /// use std::convert::Infallible;
+ /// use tower::Service;
+ /// use tower::make::MakeService;
+ /// use tower::service_fn;
+ ///
+ /// # fn main() {
+ /// # async {
+ /// // A `MakeService`
+ /// let make_service = service_fn(|make_req: ()| async {
+ /// Ok::<_, Infallible>(service_fn(|req: String| async {
+ /// Ok::<_, Infallible>(req)
+ /// }))
+ /// });
+ ///
+ /// // Convert the `MakeService` into a `Service`
+ /// let mut svc = make_service.into_service();
+ ///
+ /// // Make a new service
+ /// let mut new_svc = svc.call(()).await.unwrap();
+ ///
+ /// // Call the service
+ /// let res = new_svc.call("foo".to_string()).await.unwrap();
+ /// # };
+ /// # }
+ /// ```
+ fn into_service(self) -> IntoService<Self, Request>
+ where
+ Self: Sized,
+ {
+ IntoService {
+ make: self,
+ _marker: PhantomData,
+ }
+ }
+
+ /// Convert this [`MakeService`] into a [`Service`] without consuming the original [`MakeService`].
+ ///
+ /// # Example
+ /// ```
+ /// use std::convert::Infallible;
+ /// use tower::Service;
+ /// use tower::make::MakeService;
+ /// use tower::service_fn;
+ ///
+ /// # fn main() {
+ /// # async {
+ /// // A `MakeService`
+ /// let mut make_service = service_fn(|make_req: ()| async {
+ /// Ok::<_, Infallible>(service_fn(|req: String| async {
+ /// Ok::<_, Infallible>(req)
+ /// }))
+ /// });
+ ///
+ /// // Convert the `MakeService` into a `Service`
+ /// let mut svc = make_service.as_service();
+ ///
+ /// // Make a new service
+ /// let mut new_svc = svc.call(()).await.unwrap();
+ ///
+ /// // Call the service
+ /// let res = new_svc.call("foo".to_string()).await.unwrap();
+ ///
+ /// // The original `MakeService` is still accessible
+ /// let new_svc = make_service.make_service(()).await.unwrap();
+ /// # };
+ /// # }
+ /// ```
+ fn as_service(&mut self) -> AsService<Self, Request>
+ where
+ Self: Sized,
+ {
+ AsService {
+ make: self,
+ _marker: PhantomData,
+ }
+ }
+}
+
+impl<M, S, Target, Request> Sealed<(Target, Request)> for M
+where
+ M: Service<Target, Response = S>,
+ S: Service<Request>,
+{
+}
+
+impl<M, S, Target, Request> MakeService<Target, Request> for M
+where
+ M: Service<Target, Response = S>,
+ S: Service<Request>,
+{
+ type Response = S::Response;
+ type Error = S::Error;
+ type Service = S;
+ type MakeError = M::Error;
+ type Future = M::Future;
+
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::MakeError>> {
+ Service::poll_ready(self, cx)
+ }
+
+ fn make_service(&mut self, target: Target) -> Self::Future {
+ Service::call(self, target)
+ }
+}
+
+/// Service returned by [`MakeService::into_service`][into].
+///
+/// See the documentation on [`into_service`][into] for details.
+///
+/// [into]: MakeService::into_service
+pub struct IntoService<M, Request> {
+ make: M,
+ _marker: PhantomData<Request>,
+}
+
+impl<M, Request> Clone for IntoService<M, Request>
+where
+ M: Clone,
+{
+ fn clone(&self) -> Self {
+ Self {
+ make: self.make.clone(),
+ _marker: PhantomData,
+ }
+ }
+}
+
+impl<M, Request> fmt::Debug for IntoService<M, Request>
+where
+ M: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("IntoService")
+ .field("make", &self.make)
+ .finish()
+ }
+}
+
+impl<M, S, Target, Request> Service<Target> for IntoService<M, Request>
+where
+ M: Service<Target, Response = S>,
+ S: Service<Request>,
+{
+ type Response = M::Response;
+ type Error = M::Error;
+ type Future = M::Future;
+
+ #[inline]
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ self.make.poll_ready(cx)
+ }
+
+ #[inline]
+ fn call(&mut self, target: Target) -> Self::Future {
+ self.make.make_service(target)
+ }
+}
+
+/// Service returned by [`MakeService::as_service`][as].
+///
+/// See the documentation on [`as_service`][as] for details.
+///
+/// [as]: MakeService::as_service
+pub struct AsService<'a, M, Request> {
+ make: &'a mut M,
+ _marker: PhantomData<Request>,
+}
+
+impl<M, Request> fmt::Debug for AsService<'_, M, Request>
+where
+ M: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("AsService")
+ .field("make", &self.make)
+ .finish()
+ }
+}
+
+impl<M, S, Target, Request> Service<Target> for AsService<'_, M, Request>
+where
+ M: Service<Target, Response = S>,
+ S: Service<Request>,
+{
+ type Response = M::Response;
+ type Error = M::Error;
+ type Future = M::Future;
+
+ #[inline]
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ self.make.poll_ready(cx)
+ }
+
+ #[inline]
+ fn call(&mut self, target: Target) -> Self::Future {
+ self.make.make_service(target)
+ }
+}
diff --git a/vendor/tower/src/make/make_service/shared.rs b/vendor/tower/src/make/make_service/shared.rs
new file mode 100644
index 00000000..2b2bc026
--- /dev/null
+++ b/vendor/tower/src/make/make_service/shared.rs
@@ -0,0 +1,146 @@
+use std::convert::Infallible;
+use std::task::{Context, Poll};
+use tower_service::Service;
+
+/// A [`MakeService`] that produces services by cloning an inner service.
+///
+/// [`MakeService`]: super::MakeService
+///
+/// # Example
+///
+/// ```
+/// # use std::task::{Context, Poll};
+/// # use std::pin::Pin;
+/// # use std::convert::Infallible;
+/// use tower::make::{MakeService, Shared};
+/// use tower::buffer::Buffer;
+/// use tower::Service;
+/// use futures::future::{Ready, ready};
+///
+/// // An example connection type
+/// struct Connection {}
+///
+/// // An example request type
+/// struct Request {}
+///
+/// // An example response type
+/// struct Response {}
+///
+/// // Some service that doesn't implement `Clone`
+/// struct MyService;
+///
+/// impl Service<Request> for MyService {
+/// type Response = Response;
+/// type Error = Infallible;
+/// type Future = Ready<Result<Response, Infallible>>;
+///
+/// fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+/// Poll::Ready(Ok(()))
+/// }
+///
+/// fn call(&mut self, req: Request) -> Self::Future {
+/// ready(Ok(Response {}))
+/// }
+/// }
+///
+/// // Example function that runs a service by accepting new connections and using
+/// // `Make` to create new services that might be bound to the connection.
+/// //
+/// // This is similar to what you might find in hyper.
+/// async fn serve_make_service<Make>(make: Make)
+/// where
+/// Make: MakeService<Connection, Request>
+/// {
+/// // ...
+/// }
+///
+/// # async {
+/// // Our service
+/// let svc = MyService;
+///
+/// // Make it `Clone` by putting a channel in front
+/// let buffered = Buffer::new(svc, 1024);
+///
+/// // Convert it into a `MakeService`
+/// let make = Shared::new(buffered);
+///
+/// // Run the service and just ignore the `Connection`s as `MyService` doesn't need them
+/// serve_make_service(make).await;
+/// # };
+/// ```
+#[derive(Debug, Clone, Copy)]
+pub struct Shared<S> {
+ service: S,
+}
+
+impl<S> Shared<S> {
+ /// Create a new [`Shared`] from a service.
+ pub const fn new(service: S) -> Self {
+ Self { service }
+ }
+}
+
+impl<S, T> Service<T> for Shared<S>
+where
+ S: Clone,
+{
+ type Response = S;
+ type Error = Infallible;
+ type Future = SharedFuture<S>;
+
+ fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ Poll::Ready(Ok(()))
+ }
+
+ fn call(&mut self, _target: T) -> Self::Future {
+ SharedFuture::new(futures_util::future::ready(Ok(self.service.clone())))
+ }
+}
+
+opaque_future! {
+ /// Response future from [`Shared`] services.
+ pub type SharedFuture<S> = futures_util::future::Ready<Result<S, Infallible>>;
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::make::MakeService;
+ use crate::service_fn;
+ use futures::future::poll_fn;
+
+ async fn echo<R>(req: R) -> Result<R, Infallible> {
+ Ok(req)
+ }
+
+ #[tokio::test]
+ async fn as_make_service() {
+ let mut shared = Shared::new(service_fn(echo::<&'static str>));
+
+ poll_fn(|cx| MakeService::<(), _>::poll_ready(&mut shared, cx))
+ .await
+ .unwrap();
+ let mut svc = shared.make_service(()).await.unwrap();
+
+ poll_fn(|cx| svc.poll_ready(cx)).await.unwrap();
+ let res = svc.call("foo").await.unwrap();
+
+ assert_eq!(res, "foo");
+ }
+
+ #[tokio::test]
+ async fn as_make_service_into_service() {
+ let shared = Shared::new(service_fn(echo::<&'static str>));
+ let mut shared = MakeService::<(), _>::into_service(shared);
+
+ poll_fn(|cx| Service::<()>::poll_ready(&mut shared, cx))
+ .await
+ .unwrap();
+ let mut svc = shared.call(()).await.unwrap();
+
+ poll_fn(|cx| svc.poll_ready(cx)).await.unwrap();
+ let res = svc.call("foo").await.unwrap();
+
+ assert_eq!(res, "foo");
+ }
+}
diff --git a/vendor/tower/src/make/mod.rs b/vendor/tower/src/make/mod.rs
new file mode 100644
index 00000000..a377f2a2
--- /dev/null
+++ b/vendor/tower/src/make/mod.rs
@@ -0,0 +1,14 @@
+//! Trait aliases for Services that produce specific types of Responses.
+
+mod make_connection;
+mod make_service;
+
+pub use self::make_connection::MakeConnection;
+pub use self::make_service::shared::Shared;
+pub use self::make_service::{AsService, IntoService, MakeService};
+
+pub mod future {
+ //! Future types
+
+ pub use super::make_service::shared::SharedFuture;
+}