Skip to main content

ntex_service/
map_init_err.rs

1use std::{fmt, marker::PhantomData};
2
3use super::ServiceFactory;
4
5/// Service factory produced by the `map_init_err` combinator.
6///
7/// This is created by the `ServiceChainFactory::map_init_err()` method.
8pub struct MapInitErr<F, Sf, Err> {
9    f: F,
10    sf: Sf,
11    e: PhantomData<fn() -> Err>,
12}
13
14impl<F, Sf, Err> MapInitErr<F, Sf, Err> {
15    /// Creates a new `MapInitErr` factory.
16    pub(crate) fn new<St, Req>(f: F, sf: Sf) -> Self
17    where
18        Sf: ServiceFactory<St, Req>,
19        F: Fn(Sf::InitError) -> Err,
20    {
21        Self {
22            f,
23            sf,
24            e: PhantomData,
25        }
26    }
27}
28
29impl<F, Sf, Err> Clone for MapInitErr<F, Sf, Err>
30where
31    F: Clone,
32    Sf: Clone,
33{
34    fn clone(&self) -> Self {
35        Self {
36            f: self.f.clone(),
37            sf: self.sf.clone(),
38            e: PhantomData,
39        }
40    }
41}
42
43impl<F, Sf, Err> fmt::Debug for MapInitErr<F, Sf, Err>
44where
45    Sf: fmt::Debug,
46{
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        f.debug_struct("MapInitErr")
49            .field("sf", &self.sf)
50            .field("map", &std::any::type_name::<F>())
51            .finish()
52    }
53}
54
55impl<F, Sf, St, Req, Err> ServiceFactory<St, Req> for MapInitErr<F, Sf, Err>
56where
57    F: Fn(Sf::InitError) -> Err + Clone,
58    Sf: ServiceFactory<St, Req>,
59{
60    type Res = Sf::Res;
61    type Error = Sf::Error;
62
63    type Service = Sf::Service;
64    type InitError = Err;
65
66    #[inline]
67    async fn create(&self, st: &St) -> Result<Self::Service, Self::InitError> {
68        self.sf.create(st).await.map_err(|e| (self.f)(e))
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use crate::{ServiceFactory, factory, fn_factory, fn_service};
75
76    #[ntex::test]
77    async fn map_init_err() {
78        let factory = factory(fn_factory(async move |err: &bool| {
79            if *err {
80                Err(())
81            } else {
82                Ok(fn_service(async |i: usize| Ok::<_, ()>(i * 2)))
83            }
84        }))
85        .map_init_err(|()| std::io::Error::other("err"))
86        .clone();
87
88        assert!(factory.create(&true).await.is_err());
89        assert!(factory.create(&false).await.is_ok());
90        let _ = format!("{factory:?}");
91    }
92
93    #[ntex::test]
94    async fn map_init_err2() {
95        let factory = factory(fn_factory(async |err: &bool| {
96            if *err {
97                Err(())
98            } else {
99                Ok(fn_service(async |i: usize| Ok::<_, ()>(i * 2)))
100            }
101        }))
102        .map_init_err(|()| std::io::Error::other("err"))
103        .clone();
104
105        assert!(factory.create(&true).await.is_err());
106        assert!(factory.create(&false).await.is_ok());
107        let _ = format!("{factory:?}");
108    }
109}