1use alloc::{boxed::Box, rc::Rc};
4use core::{future::Future, pin::Pin};
5
6use crate::{Service, ServiceFactory};
7
8pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T>>>;
10
11pub type BoxService<Req, Res, Err> =
13 Box<dyn Service<Req, Response = Res, Error = Err, Future = BoxFuture<Result<Res, Err>>>>;
14
15pub fn service<S, Req>(service: S) -> BoxService<Req, S::Response, S::Error>
17where
18 S: Service<Req> + 'static,
19 Req: 'static,
20 S::Future: 'static,
21{
22 Box::new(ServiceWrapper::new(service))
23}
24
25pub type RcService<Req, Res, Err> =
27 Rc<dyn Service<Req, Response = Res, Error = Err, Future = BoxFuture<Result<Res, Err>>>>;
28
29pub fn rc_service<S, Req>(service: S) -> RcService<Req, S::Response, S::Error>
31where
32 S: Service<Req> + 'static,
33 Req: 'static,
34 S::Future: 'static,
35{
36 Rc::new(ServiceWrapper::new(service))
37}
38
39struct ServiceWrapper<S> {
40 inner: S,
41}
42
43impl<S> ServiceWrapper<S> {
44 fn new(inner: S) -> Self {
45 Self { inner }
46 }
47}
48
49impl<S, Req, Res, Err> Service<Req> for ServiceWrapper<S>
50where
51 S: Service<Req, Response = Res, Error = Err>,
52 S::Future: 'static,
53{
54 type Response = Res;
55 type Error = Err;
56 type Future = BoxFuture<Result<Res, Err>>;
57
58 crate::forward_ready!(inner);
59
60 fn call(&self, req: Req) -> Self::Future {
61 Box::pin(self.inner.call(req))
62 }
63}
64
65pub struct BoxServiceFactory<Cfg, Req, Res, Err, InitErr>(Inner<Cfg, Req, Res, Err, InitErr>);
67
68pub fn factory<SF, Req>(
70 factory: SF,
71) -> BoxServiceFactory<SF::Config, Req, SF::Response, SF::Error, SF::InitError>
72where
73 SF: ServiceFactory<Req> + 'static,
74 Req: 'static,
75 SF::Response: 'static,
76 SF::Service: 'static,
77 SF::Future: 'static,
78 SF::Error: 'static,
79 SF::InitError: 'static,
80{
81 BoxServiceFactory(Box::new(FactoryWrapper(factory)))
82}
83
84type Inner<C, Req, Res, Err, InitErr> = Box<
85 dyn ServiceFactory<
86 Req,
87 Config = C,
88 Response = Res,
89 Error = Err,
90 InitError = InitErr,
91 Service = BoxService<Req, Res, Err>,
92 Future = BoxFuture<Result<BoxService<Req, Res, Err>, InitErr>>,
93 >,
94>;
95
96impl<C, Req, Res, Err, InitErr> ServiceFactory<Req> for BoxServiceFactory<C, Req, Res, Err, InitErr>
97where
98 Req: 'static,
99 Res: 'static,
100 Err: 'static,
101 InitErr: 'static,
102{
103 type Response = Res;
104 type Error = Err;
105 type Config = C;
106 type Service = BoxService<Req, Res, Err>;
107 type InitError = InitErr;
108
109 type Future = BoxFuture<Result<Self::Service, InitErr>>;
110
111 fn new_service(&self, cfg: C) -> Self::Future {
112 self.0.new_service(cfg)
113 }
114}
115
116struct FactoryWrapper<SF>(SF);
117
118impl<SF, Req, Cfg, Res, Err, InitErr> ServiceFactory<Req> for FactoryWrapper<SF>
119where
120 Req: 'static,
121 Res: 'static,
122 Err: 'static,
123 InitErr: 'static,
124 SF: ServiceFactory<Req, Config = Cfg, Response = Res, Error = Err, InitError = InitErr>,
125 SF::Future: 'static,
126 SF::Service: 'static,
127 <SF::Service as Service<Req>>::Future: 'static,
128{
129 type Response = Res;
130 type Error = Err;
131 type Config = Cfg;
132 type Service = BoxService<Req, Res, Err>;
133 type InitError = InitErr;
134 type Future = BoxFuture<Result<Self::Service, Self::InitError>>;
135
136 fn new_service(&self, cfg: Cfg) -> Self::Future {
137 let f = self.0.new_service(cfg);
138 Box::pin(async { f.await.map(|s| Box::new(ServiceWrapper::new(s)) as _) })
139 }
140}