1#![doc(html_root_url = "https://docs.rs/tsukuyomi-service/0.1.0")]
6#![deny(
7 missing_docs,
8 missing_debug_implementations,
9 nonstandard_style,
10 rust_2018_idioms,
11 rust_2018_compatibility,
12 unused
13)]
14#![forbid(clippy::unimplemented)]
15
16use futures::{Async, Future, IntoFuture, Poll};
17
18#[doc(no_inline)]
19pub use tower_service::Service;
20
21pub fn service_fn<Request, R>(
23 f: impl FnMut(Request) -> R,
24) -> impl Service<
25 Request, Response = R::Item,
27 Error = R::Error,
28 Future = R::Future,
29>
30where
31 R: IntoFuture,
32{
33 #[allow(missing_debug_implementations)]
34 struct ServiceFn<F>(F);
35
36 impl<F, Request, R> Service<Request> for ServiceFn<F>
37 where
38 F: FnMut(Request) -> R,
39 R: IntoFuture,
40 {
41 type Response = R::Item;
42 type Error = R::Error;
43 type Future = R::Future;
44
45 #[inline]
46 fn poll_ready(&mut self) -> Poll<(), Self::Error> {
47 Ok(Async::Ready(()))
48 }
49
50 #[inline]
51 fn call(&mut self, request: Request) -> Self::Future {
52 (self.0)(request).into_future()
53 }
54 }
55
56 ServiceFn(f)
57}
58
59pub trait MakeService<Ctx, Request> {
68 type Response;
70 type Error;
72 type Service: Service<Request, Response = Self::Response, Error = Self::Error>;
74 type MakeError;
76 type Future: Future<Item = Self::Service, Error = Self::MakeError>;
78
79 fn make_service(&self, ctx: Ctx) -> Self::Future;
81}
82
83#[allow(missing_docs)]
85pub trait MakeServiceRef<Ctx, Request> {
86 type Response;
87 type Error;
88 type Service: Service<Request, Response = Self::Response, Error = Self::Error>;
89 type MakeError;
90 type Future: Future<Item = Self::Service, Error = Self::MakeError>;
91
92 fn make_service_ref(&self, ctx: &Ctx) -> Self::Future;
93}
94
95impl<S, T, Req, Res, Err, Svc, MkErr, Fut> MakeServiceRef<T, Req> for S
96where
97 for<'a> S: MakeService<
98 &'a T,
99 Req,
100 Response = Res,
101 Error = Err,
102 Service = Svc,
103 MakeError = MkErr,
104 Future = Fut,
105 >,
106 Svc: Service<Req, Response = Res, Error = Err>,
107 Fut: Future<Item = Svc, Error = MkErr>,
108{
109 type Response = Res;
110 type Error = Err;
111 type Service = Svc;
112 type MakeError = MkErr;
113 type Future = Fut;
114
115 #[inline]
116 fn make_service_ref(&self, ctx: &T) -> Self::Future {
117 MakeService::make_service(self, ctx)
118 }
119}
120
121pub fn make_service<Request, Ctx, R>(
123 f: impl Fn(Ctx) -> R,
124) -> impl MakeService<
125 Ctx, Request,
127 Response = <R::Item as Service<Request>>::Response,
128 Error = <R::Item as Service<Request>>::Error,
129 Service = R::Item,
130 MakeError = R::Error,
131 Future = R::Future,
132>
133where
134 R: IntoFuture,
135 R::Item: Service<Request>,
136{
137 #[allow(missing_debug_implementations)]
138 struct MakeServiceFn<F>(F);
139
140 impl<F, Request, Ctx, R> MakeService<Ctx, Request> for MakeServiceFn<F>
141 where
142 F: Fn(Ctx) -> R,
143 R: IntoFuture,
144 R::Item: Service<Request>,
145 {
146 type Response = <R::Item as Service<Request>>::Response;
147 type Error = <R::Item as Service<Request>>::Error;
148 type Service = R::Item;
149 type MakeError = R::Error;
150 type Future = R::Future;
151
152 #[inline]
153 fn make_service(&self, ctx: Ctx) -> Self::Future {
154 (self.0)(ctx).into_future()
155 }
156 }
157
158 MakeServiceFn(f)
159}
160
161pub fn make_service_ref<Request, Ctx, R>(
163 f: impl Fn(&Ctx) -> R,
164) -> impl for<'a> MakeService<
165 &'a Ctx, Request,
167 Response = <R::Item as Service<Request>>::Response,
168 Error = <R::Item as Service<Request>>::Error,
169 Service = R::Item,
170 MakeError = R::Error,
171 Future = R::Future,
172>
173where
174 R: IntoFuture,
175 R::Item: Service<Request>,
176{
177 #[allow(missing_debug_implementations)]
178 struct MakeServiceRefFn<F>(F);
179
180 impl<'a, F, Request, Ctx, R> MakeService<&'a Ctx, Request> for MakeServiceRefFn<F>
181 where
182 F: Fn(&Ctx) -> R,
183 R: IntoFuture,
184 R::Item: Service<Request>,
185 {
186 type Response = <R::Item as Service<Request>>::Response;
187 type Error = <R::Item as Service<Request>>::Error;
188 type Service = R::Item;
189 type MakeError = R::Error;
190 type Future = R::Future;
191
192 #[inline]
193 fn make_service(&self, ctx: &'a Ctx) -> Self::Future {
194 (self.0)(ctx).into_future()
195 }
196 }
197
198 MakeServiceRefFn(f)
199}
200
201pub trait ModifyService<Ctx, Request, S> {
203 type Response;
205 type Error;
207 type Service: Service<Request, Response = Self::Response, Error = Self::Error>;
209 type ModifyError;
211 type Future: Future<Item = Self::Service, Error = Self::ModifyError>;
213
214 fn modify_service(&self, input: S, ctx: Ctx) -> Self::Future;
216}
217
218impl<Ctx, Request, S> ModifyService<Ctx, Request, S> for ()
219where
220 S: Service<Request>,
221{
222 type Response = S::Response;
223 type Error = S::Error;
224 type Service = S;
225 type ModifyError = std::io::Error;
226 type Future = futures::future::FutureResult<Self::Service, Self::ModifyError>;
227
228 #[inline]
229 fn modify_service(&self, input: S, _: Ctx) -> Self::Future {
230 futures::future::ok(input)
231 }
232}
233
234#[allow(missing_docs)]
236pub trait ModifyServiceRef<Ctx, Request, S> {
237 type Response;
238 type Error;
239 type Service: Service<Request, Response = Self::Response, Error = Self::Error>;
240 type ModifyError;
241 type Future: Future<Item = Self::Service, Error = Self::ModifyError>;
242
243 fn modify_service_ref(&self, input: S, ctx: &Ctx) -> Self::Future;
244}
245
246impl<M, SvcIn, SvcOut, Ctx, Req, Res, Err, ModErr, Fut> ModifyServiceRef<Ctx, Req, SvcIn> for M
247where
248 for<'a> M: ModifyService<
249 &'a Ctx,
250 Req,
251 SvcIn,
252 Response = Res,
253 Error = Err,
254 Service = SvcOut,
255 ModifyError = ModErr,
256 Future = Fut,
257 >,
258 SvcOut: Service<Req, Response = Res, Error = Err>,
259 Fut: Future<Item = SvcOut, Error = ModErr>,
260{
261 type Response = Res;
262 type Error = Err;
263 type Service = SvcOut;
264 type ModifyError = ModErr;
265 type Future = Fut;
266
267 fn modify_service_ref(&self, input: SvcIn, ctx: &Ctx) -> Self::Future {
268 ModifyService::modify_service(self, input, ctx)
269 }
270}
271
272pub fn modify_service<Request, S, Ctx, R>(
274 f: impl Fn(S, Ctx) -> R,
275) -> impl ModifyService<
276 Ctx, Request,
278 S,
279 Response = <R::Item as Service<Request>>::Response,
280 Error = <R::Item as Service<Request>>::Error,
281 Service = R::Item,
282 ModifyError = R::Error,
283 Future = R::Future,
284>
285where
286 R: IntoFuture,
287 R::Item: Service<Request>,
288{
289 #[allow(missing_debug_implementations)]
290 struct ModifyServiceFn<F>(F);
291
292 impl<F, Request, S, Ctx, R> ModifyService<Ctx, Request, S> for ModifyServiceFn<F>
293 where
294 F: Fn(S, Ctx) -> R,
295 R: IntoFuture,
296 R::Item: Service<Request>,
297 {
298 type Response = <R::Item as Service<Request>>::Response;
299 type Error = <R::Item as Service<Request>>::Error;
300 type Service = R::Item;
301 type ModifyError = R::Error;
302 type Future = R::Future;
303
304 #[inline]
305 fn modify_service(&self, input: S, ctx: Ctx) -> Self::Future {
306 (self.0)(input, ctx).into_future()
307 }
308 }
309
310 ModifyServiceFn(f)
311}
312
313pub fn modify_service_ref<Request, S, Ctx, R>(
315 f: impl Fn(S, &Ctx) -> R,
316) -> impl for<'a> ModifyService<
317 &'a Ctx, Request,
319 S,
320 Response = <R::Item as Service<Request>>::Response,
321 Error = <R::Item as Service<Request>>::Error,
322 Service = R::Item,
323 ModifyError = R::Error,
324 Future = R::Future,
325>
326where
327 R: IntoFuture,
328 R::Item: Service<Request>,
329{
330 #[allow(missing_debug_implementations)]
331 struct ModifyServiceRefFn<F>(F);
332
333 impl<'a, F, Request, S, Ctx, R> ModifyService<&'a Ctx, Request, S> for ModifyServiceRefFn<F>
334 where
335 F: Fn(S, &Ctx) -> R,
336 R: IntoFuture,
337 R::Item: Service<Request>,
338 {
339 type Response = <R::Item as Service<Request>>::Response;
340 type Error = <R::Item as Service<Request>>::Error;
341 type Service = R::Item;
342 type ModifyError = R::Error;
343 type Future = R::Future;
344
345 #[inline]
346 fn modify_service(&self, input: S, ctx: &'a Ctx) -> Self::Future {
347 (self.0)(input, ctx).into_future()
348 }
349 }
350
351 ModifyServiceRefFn(f)
352}