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