Skip to main content

burger/
map.rs

1//! The [`ServiceExt::map`](crate::ServiceExt::map) combinator returns [`Map`], which extends a
2//! service with a specified closure from the modifying the [`Service::Response`].
3//!
4//! For an asynchronous version of this combinator see [then](mod@crate::then) module.
5//!
6//! # Example
7//!
8//! ```rust
9//! use burger::*;
10//!
11//! # #[tokio::main]
12//! # async fn main() {
13//! let svc = service_fn(|x: u32| async move { x.to_string() }).map(|x: String| x.parse());
14//! let response: usize = svc.oneshot(32).await.unwrap();
15//! assert_eq!(response, 32);
16//! # }
17//! ```
18//!
19//! # Load
20//!
21//! [`Load`](crate::load::Load) measurements defer to the inner service.
22
23use std::{any, fmt};
24
25use crate::{Middleware, Service};
26
27/// A wrapper [`Service`] for the [`ServiceExt::map`](crate::ServiceExt::map) combinator.
28///
29/// See the [module](crate::map) for more information.
30#[derive(Clone, Debug)]
31pub struct Map<S, F> {
32    inner: S,
33    closure: F,
34}
35
36impl<S, F> Map<S, F> {
37    pub(crate) fn new(inner: S, closure: F) -> Self {
38        Self { inner, closure }
39    }
40}
41
42/// The [`Service::Permit`] type for [Map].
43pub struct MapPermit<'a, S, F, Request>
44where
45    S: Service<Request> + 'a,
46{
47    inner: S::Permit<'a>,
48    closure: &'a F,
49}
50
51impl<'a, S, F, Request> fmt::Debug for MapPermit<'a, S, F, Request>
52where
53    S: Service<Request>,
54    S::Permit<'a>: fmt::Debug,
55{
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        f.debug_struct("MapPermit")
58            .field("inner", &self.inner)
59            .field("closure", &format_args!("{}", any::type_name::<F>()))
60            .finish()
61    }
62}
63
64impl<Request, S, F, Output> Service<Request> for Map<S, F>
65where
66    S: Service<Request>,
67    F: Fn(S::Response) -> Output,
68{
69    type Response = Output;
70    type Permit<'a> = MapPermit<'a, S, F, Request> where S: 'a, F: 'a;
71
72    async fn acquire(&self) -> Self::Permit<'_> {
73        MapPermit {
74            inner: self.inner.acquire().await,
75            closure: &self.closure,
76        }
77    }
78
79    async fn call(permit: Self::Permit<'_>, request: Request) -> Self::Response {
80        (permit.closure)(S::call(permit.inner, request).await)
81    }
82}
83
84impl<S, T, F> Middleware<S> for Map<T, F>
85where
86    T: Middleware<S>,
87{
88    type Service = Map<T::Service, F>;
89
90    fn apply(self, svc: S) -> Self::Service {
91        let Self { inner, closure } = self;
92        Map {
93            inner: inner.apply(svc),
94            closure,
95        }
96    }
97}