Skip to content

Commit b19de6f

Browse files
committed
Add support for impl Middleware to allow closure middleware
1 parent ff5f57e commit b19de6f

File tree

4 files changed

+25
-39
lines changed

4 files changed

+25
-39
lines changed

examples/middleware.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::future::Future;
2-
use std::pin::Pin;
31
use std::sync::atomic::{AtomicUsize, Ordering};
42
use std::sync::Arc;
53

@@ -25,19 +23,17 @@ impl UserDatabase {
2523
// This is an example of a function middleware that uses the
2624
// application state. Because it depends on a specific request state,
2725
// it would likely be closely tied to a specific application
28-
fn user_loader(mut request: Request, next: Next) -> Pin<Box<dyn Future<Output = Result> + Send>> {
29-
Box::pin(async {
30-
if let Some(user) = request.state().find_user().await {
31-
tide::log::trace!("user loaded", {user: user.name});
32-
request.set_ext(user);
33-
Ok(next.run(request).await)
34-
// this middleware only needs to run before the endpoint, so
35-
// it just passes through the result of Next
36-
} else {
37-
// do not run endpoints, we could not find a user
38-
Ok(Response::new(StatusCode::Unauthorized))
39-
}
40-
})
26+
async fn user_loader(mut request: Request, next: Next) -> Result {
27+
if let Some(user) = request.state().find_user().await {
28+
tide::log::trace!("user loaded", {user: user.name});
29+
request.set_ext(user);
30+
Ok(next.run(request).await)
31+
// this middleware only needs to run before the endpoint, so
32+
// it just passes through the result of Next
33+
} else {
34+
// do not run endpoints, we could not find a user
35+
Ok(Response::new(StatusCode::Unauthorized))
36+
}
4137
}
4238

4339
// This is an example of middleware that keeps its own state and could

src/middleware.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use std::sync::Arc;
55
use crate::{Endpoint, Request, Response};
66
use async_trait::async_trait;
77
use std::future::Future;
8-
use std::pin::Pin;
98

109
/// Middleware that wraps around the remaining middleware chain.
1110
#[async_trait]
@@ -20,15 +19,16 @@ pub trait Middleware: Send + Sync + 'static {
2019
}
2120

2221
#[async_trait]
23-
impl<F> Middleware for F
22+
impl<F, Fut, Res> Middleware for F
2423
where
25-
F: Send
26-
+ Sync
27-
+ 'static
28-
+ Fn(Request, Next) -> Pin<Box<dyn Future<Output = crate::Result> + Send>>,
24+
F: Send + Sync + 'static + Fn(Request, Next) -> Fut,
25+
Fut: Future<Output = crate::Result<Res>> + Send + 'static,
26+
Res: Into<Response> + 'static,
2927
{
3028
async fn handle(&self, req: Request, next: Next) -> crate::Result {
31-
(self)(req, next).await
29+
let fut = (self)(req, next);
30+
let res = fut.await?;
31+
Ok(res.into())
3232
}
3333
}
3434

src/server.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,7 @@ where
181181
///
182182
/// Middleware can only be added at the "top level" of an application, and is processed in the
183183
/// order in which it is applied.
184-
pub fn with<M>(&mut self, middleware: M) -> &mut Self
185-
where
186-
M: Middleware,
187-
{
184+
pub fn with(&mut self, middleware: impl Middleware) -> &mut Self {
188185
log::trace!("Adding middleware {}", middleware.name());
189186
let m = Arc::get_mut(&mut self.middleware)
190187
.expect("Registering middleware is not possible after the Server has started");

tests/function_middleware.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
1-
use std::future::Future;
2-
use std::pin::Pin;
31
use tide::http::{self, url::Url, Method};
42

53
mod test_utils;
64

7-
fn auth_middleware(
8-
request: tide::Request,
9-
next: tide::Next,
10-
) -> Pin<Box<dyn Future<Output = tide::Result> + Send>> {
5+
async fn auth_middleware(request: tide::Request, next: tide::Next) -> tide::Result {
116
let authenticated = match request.header("X-Auth") {
127
Some(header) => header == "secret_key",
138
None => false,
149
};
1510

16-
Box::pin(async move {
17-
if authenticated {
18-
Ok(next.run(request).await)
19-
} else {
20-
Ok(tide::Response::new(tide::StatusCode::Unauthorized))
21-
}
22-
})
11+
if authenticated {
12+
Ok(next.run(request).await)
13+
} else {
14+
Ok(tide::Response::new(tide::StatusCode::Unauthorized))
15+
}
2316
}
2417

2518
async fn echo_path(req: tide::Request) -> tide::Result<String> {

0 commit comments

Comments
 (0)