[go: up one dir, main page]

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}