zon_middleware/
map_request.rs

1use std::future::Future;
2
3use zon_core::{HttpMiddleware, HttpService};
4
5/// Middleware to modify a request.
6///
7/// Currently, this middleware only accepts an `Fn(http::Request<B>) ->
8/// http::Request<B>`. `FromRequest[Parts]` and `IntoResponse` return types are
9/// going to be supported in the future.
10#[derive(Clone, Copy, Debug)]
11pub struct MapRequest<F> {
12    map_fn: F,
13}
14
15impl<F> MapRequest<F> {
16    pub fn new(map_fn: F) -> Self {
17        Self { map_fn }
18    }
19}
20
21impl<S, F> HttpMiddleware<S> for MapRequest<F> {
22    type Service = MapRequestService<S, F>;
23
24    fn apply(self, inner: S) -> Self::Service {
25        MapRequestService::new(inner, self.map_fn)
26    }
27}
28
29pub struct MapRequestService<S, F> {
30    inner: S,
31    map_fn: F,
32}
33
34impl<S, F> MapRequestService<S, F> {
35    pub fn new(inner: S, map_fn: F) -> Self {
36        Self { inner, map_fn }
37    }
38}
39
40impl<S, F, Fut, B, B2> HttpService<B> for MapRequestService<S, F>
41where
42    S: HttpService<B2>,
43    F: Fn(http::Request<B>) -> Fut + Sync,
44    Fut: Future<Output = http::Request<B2>> + Send,
45    B: Send,
46    B2: Send,
47{
48    type ResponseBody = S::ResponseBody;
49
50    async fn call(&self, request: http::Request<B>) -> http::Response<Self::ResponseBody> {
51        let request = (self.map_fn)(request).await;
52        self.inner.call(request).await
53    }
54}