builder: Add ServiceBuilder::service_fn (#564)

* builder: Add `ServiceBuilder::service_fn`

A small convenience for doing `.service(service_fn(handler_function))`.

* Docs tweaks

* Apply suggestions from code review

Co-authored-by: Eliza Weisman <eliza@buoyant.io>

* Fix

Co-authored-by: Eliza Weisman <eliza@buoyant.io>
This commit is contained in:
David Pedersen 2021-02-25 22:52:37 +01:00 committed by GitHub
parent 9948f2561d
commit 7461abc6b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 0 deletions

View File

@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **builder**: Add `ServiceBuilder::layer_fn` to add a layer built from a function.
- **builder**: Add `ServiceBuilder::map_future` for transforming the futures produced
by a service.
- **builder**: Add `ServiceBuilder::service_fn` for applying `Layer`s to an
async function using `util::service_fn`.
- **util**: Add example for `service_fn`.
# 0.4.5 (February 10, 2021)

View File

@ -468,6 +468,58 @@ impl<L> ServiceBuilder<L> {
{
self.layer.layer(service)
}
/// Wrap the async function `F` with the middleware provided by this [`ServiceBuilder`]'s
/// [`Layer`]s, returning a new [`Service`].
///
/// This is a convenience method which is equivalent to calling
/// [`ServiceBuilder::service`] with a [`service_fn`], like this:
///
/// ```rust
/// # use tower::{ServiceBuilder, service_fn};
/// # async fn handler_fn(_: ()) -> Result<(), ()> { Ok(()) }
/// # let _ = {
/// ServiceBuilder::new()
/// // ...
/// .service(service_fn(handler_fn))
/// # };
/// ```
///
/// # Example
///
/// ```rust
/// use std::time::Duration;
/// use tower::{ServiceBuilder, ServiceExt, BoxError, service_fn};
///
/// # #[tokio::main]
/// # async fn main() -> Result<(), BoxError> {
/// async fn handle(request: &'static str) -> Result<&'static str, BoxError> {
/// Ok(request)
/// }
///
/// let svc = ServiceBuilder::new()
/// .buffer(1024)
/// .timeout(Duration::from_secs(10))
/// .service_fn(handle);
///
/// let response = svc.oneshot("foo").await?;
///
/// assert_eq!(response, "foo");
/// # Ok(())
/// # }
/// ```
///
/// [`Layer`]: crate::Layer
/// [`Service`]: crate::Service
/// [`service_fn`]: crate::service_fn
#[cfg(feature = "util")]
#[cfg_attr(docsrs, doc(cfg(feature = "util")))]
pub fn service_fn<F>(self, f: F) -> L::Service
where
L: Layer<crate::util::ServiceFn<F>>,
{
self.service(crate::util::service_fn(f))
}
}
impl<L: fmt::Debug> fmt::Debug for ServiceBuilder<L> {