use std::fmt; use std::future::Future; use std::task::{Context, Poll}; use tower_service::Service; /// Returns a new [`ServiceFn`] with the given closure. /// /// This lets you build a [`Service`] from an async function that returns a [`Result`]. /// /// # Example /// /// ``` /// use tower::{service_fn, Service, ServiceExt, BoxError}; /// # struct Request; /// # impl Request { /// # fn new() -> Self { Self } /// # } /// # struct Response(&'static str); /// # impl Response { /// # fn new(body: &'static str) -> Self { /// # Self(body) /// # } /// # fn into_body(self) -> &'static str { self.0 } /// # } /// /// # #[tokio::main] /// # async fn main() -> Result<(), BoxError> { /// async fn handle(request: Request) -> Result { /// let response = Response::new("Hello, World!"); /// Ok(response) /// } /// /// let mut service = service_fn(handle); /// /// let response = service /// .ready() /// .await? /// .call(Request::new()) /// .await?; /// /// assert_eq!("Hello, World!", response.into_body()); /// # /// # Ok(()) /// # } /// ``` pub fn service_fn(f: T) -> ServiceFn { ServiceFn { f } } /// A [`Service`] implemented by a closure. /// /// See [`service_fn`] for more details. #[derive(Copy, Clone)] pub struct ServiceFn { f: T, } impl fmt::Debug for ServiceFn { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ServiceFn") .field("f", &format_args!("{}", std::any::type_name::())) .finish() } } impl Service for ServiceFn where T: FnMut(Request) -> F, F: Future>, { type Response = R; type Error = E; type Future = F; fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { Ok(()).into() } fn call(&mut self, req: Request) -> Self::Future { (self.f)(req) } }