//! 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: 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; /// Errors produced while building a service. type MakeError; /// The future of the [`Service`] instance. type Future: Future>; /// 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>; /// 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 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 where Self: Sized, { AsService { make: self, _marker: PhantomData, } } } impl Sealed<(Target, Request)> for M where M: Service, S: Service, { } impl MakeService for M where M: Service, S: Service, { 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> { 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 { make: M, _marker: PhantomData, } impl Clone for IntoService where M: Clone, { fn clone(&self) -> Self { Self { make: self.make.clone(), _marker: PhantomData, } } } impl fmt::Debug for IntoService where M: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("IntoService") .field("make", &self.make) .finish() } } impl Service for IntoService where M: Service, S: Service, { type Response = M::Response; type Error = M::Error; type Future = M::Future; #[inline] fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { 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, } impl 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 Service for AsService<'_, M, Request> where M: Service, S: Service, { type Response = M::Response; type Error = M::Error; type Future = M::Future; #[inline] fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.make.poll_ready(cx) } #[inline] fn call(&mut self, target: Target) -> Self::Future { self.make.make_service(target) } }