tower_async/util/
service_fn.rs

1use std::fmt;
2use std::future::Future;
3use tower_async_service::Service;
4
5/// Returns a new [`ServiceFn`] with the given closure.
6///
7/// This lets you build a [`Service`] from an async function that returns a [`Result`].
8///
9/// # Example
10///
11/// ```
12/// use tower_async::{service_fn, Service, ServiceExt, BoxError};
13/// # struct Request;
14/// # impl Request {
15/// #     fn new() -> Self { Self }
16/// # }
17/// # struct Response(&'static str);
18/// # impl Response {
19/// #     fn new(body: &'static str) -> Self {
20/// #         Self(body)
21/// #     }
22/// #     fn into_body(self) -> &'static str { self.0 }
23/// # }
24///
25/// # #[tokio::main]
26/// # async fn main() -> Result<(), BoxError> {
27/// async fn handle(request: Request) -> Result<Response, BoxError> {
28///     let response = Response::new("Hello, World!");
29///     Ok(response)
30/// }
31///
32/// let mut service = service_fn(handle);
33///
34/// let response = service
35///     .call(Request::new())
36///     .await?;
37///
38/// assert_eq!("Hello, World!", response.into_body());
39/// #
40/// # Ok(())
41/// # }
42/// ```
43pub fn service_fn<T>(f: T) -> ServiceFn<T> {
44    ServiceFn { f }
45}
46
47/// A [`Service`] implemented by a closure.
48///
49/// See [`service_fn`] for more details.
50#[derive(Copy, Clone)]
51pub struct ServiceFn<T> {
52    f: T,
53}
54
55impl<T> fmt::Debug for ServiceFn<T> {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        f.debug_struct("ServiceFn")
58            .field("f", &format_args!("{}", std::any::type_name::<T>()))
59            .finish()
60    }
61}
62
63impl<T, F, Request, R, E> Service<Request> for ServiceFn<T>
64where
65    T: Fn(Request) -> F,
66    F: Future<Output = Result<R, E>>,
67{
68    type Response = R;
69    type Error = E;
70
71    async fn call(&self, req: Request) -> Result<Self::Response, Self::Error> {
72        (self.f)(req).await
73    }
74}