ntex_service/
map_init_err.rs1use std::{fmt, marker::PhantomData};
2
3use super::ServiceFactory;
4
5pub 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 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}