tide/utils.rs
1//! Miscellaneous utilities.
2
3use crate::{Middleware, Next, Request, Response};
4pub use async_trait::async_trait;
5use std::future::Future;
6
7/// Define a middleware that operates on incoming requests.
8///
9/// This middleware is useful because it is not possible in Rust yet to use
10/// closures to define inline middleware.
11///
12/// # Examples
13///
14/// ```rust
15/// use tide::{utils, Request};
16/// use std::time::Instant;
17///
18/// let mut app = tide::new();
19/// app.with(utils::Before(|mut request: Request<()>| async move {
20/// request.set_ext(Instant::now());
21/// request
22/// }));
23/// ```
24#[derive(Debug)]
25pub struct Before<F>(pub F);
26
27#[async_trait]
28impl<State, F, Fut> Middleware<State> for Before<F>
29where
30 State: Clone + Send + Sync + 'static,
31 F: Fn(Request<State>) -> Fut + Send + Sync + 'static,
32 Fut: Future<Output = Request<State>> + Send + Sync + 'static,
33{
34 async fn handle(&self, request: Request<State>, next: Next<'_, State>) -> crate::Result {
35 let request = (self.0)(request).await;
36 Ok(next.run(request).await)
37 }
38}
39
40/// Define a middleware that operates on outgoing responses.
41///
42/// This middleware is useful because it is not possible in Rust yet to use
43/// closures to define inline middleware.
44///
45/// # Examples
46///
47/// ```rust
48/// use tide::{utils, http, Response};
49///
50/// let mut app = tide::new();
51/// app.with(utils::After(|res: Response| async move {
52/// match res.status() {
53/// http::StatusCode::NotFound => Ok("Page not found".into()),
54/// http::StatusCode::InternalServerError => Ok("Something went wrong".into()),
55/// _ => Ok(res),
56/// }
57/// }));
58/// ```
59#[derive(Debug)]
60pub struct After<F>(pub F);
61#[async_trait]
62impl<State, F, Fut> Middleware<State> for After<F>
63where
64 State: Clone + Send + Sync + 'static,
65 F: Fn(Response) -> Fut + Send + Sync + 'static,
66 Fut: Future<Output = crate::Result> + Send + Sync + 'static,
67{
68 async fn handle(&self, request: Request<State>, next: Next<'_, State>) -> crate::Result {
69 let response = next.run(request).await;
70 (self.0)(response).await
71 }
72}