Skip to content

Commit

Permalink
make middleware function infer argument types and doc update for home…
Browse files Browse the repository at this point in the history
…brew AsyncFn trait
  • Loading branch information
fakeshadow committed Feb 25, 2025
1 parent d18c19f commit 080c2f2
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 9 deletions.
10 changes: 6 additions & 4 deletions client/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ impl ClientBuilder {

/// add a middleware function to client builder.
///
/// func is an async closure, that receive the next middleware in the chain and the incoming request.
/// func is an async closure receiving the next middleware in the chain and the incoming request.
///
/// # Examples
/// ```rust
Expand All @@ -134,15 +134,17 @@ impl ClientBuilder {
///
/// // start a new client builder and apply our middleware to it:
/// let builder = ClientBuilder::new()
/// // use a closure to receive HttpService and construct my middleware type.
/// .middleware_fn(async |mut req: ServiceRequest, http_service: &HttpService| {
/// // use an async closure to receive HttpService and construct my middleware type.
/// .middleware_fn(async |mut req, http_service| {
/// req.req.headers_mut().insert("x-my-header", HeaderValue::from_static("my-value"));
///
/// http_service.call(req).await
/// });
/// ```
pub fn middleware_fn<F>(mut self, func: F) -> Self
where
// bound to std::ops::AsyncFn allows us avoid explicit annotating closure argument types
F: core::ops::AsyncFn(ServiceRequest<'_, '_>, &HttpService) -> Result<Response, Error>,
// bound to homebrew AsyncFn allows us express `Send` bound to the returned future type
F: for<'s, 'r, 'c> AsyncFn<(ServiceRequest<'r, 'c>, &'s HttpService), Output = Result<Response, Error>>
+ Send
+ Sync
Expand Down
8 changes: 3 additions & 5 deletions client/src/service/async_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

use core::future::Future;

/// Same as `std::ops::Fn` trait but for async output.
///
/// It is necessary in the the HRTB bounds for async fn's with reference parameters because it
/// allows the output future to be bound to the parameter lifetime.
/// `F: for<'a> AsyncFn<(&'a u8,) Output=u8>`
// TODO: use `std::ops::AsyncFn` instead
/// Similar to `std::ops::AsyncFn` except the associated types are named and their trait bounds can be annotated.
/// It's necessary to express `Send` bound on the `Future` associated type.
pub trait AsyncFn<Arg> {
type Output;
type Future: Future<Output = Self::Output>;
Expand Down

0 comments on commit 080c2f2

Please sign in to comment.