83 lines
1.9 KiB
Rust
83 lines
1.9 KiB
Rust
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<Response, BoxError> {
|
|
/// 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<T>(f: T) -> ServiceFn<T> {
|
|
ServiceFn { f }
|
|
}
|
|
|
|
/// A [`Service`] implemented by a closure.
|
|
///
|
|
/// See [`service_fn`] for more details.
|
|
#[derive(Copy, Clone)]
|
|
pub struct ServiceFn<T> {
|
|
f: T,
|
|
}
|
|
|
|
impl<T> fmt::Debug for ServiceFn<T> {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
f.debug_struct("ServiceFn")
|
|
.field("f", &format_args!("{}", std::any::type_name::<T>()))
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl<T, F, Request, R, E> Service<Request> for ServiceFn<T>
|
|
where
|
|
T: FnMut(Request) -> F,
|
|
F: Future<Output = Result<R, E>>,
|
|
{
|
|
type Response = R;
|
|
type Error = E;
|
|
type Future = F;
|
|
|
|
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), E>> {
|
|
Ok(()).into()
|
|
}
|
|
|
|
fn call(&mut self, req: Request) -> Self::Future {
|
|
(self.f)(req)
|
|
}
|
|
}
|