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}