1use core::{future::Future, marker::PhantomData};
2
3use crate::{ok, IntoService, IntoServiceFactory, Ready, Service, ServiceFactory};
4
5pub fn fn_service<F, Fut, Req, Res, Err, Cfg>(f: F) -> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
7where
8 F: Fn(Req) -> Fut + Clone,
9 Fut: Future<Output = Result<Res, Err>>,
10{
11 FnServiceFactory::new(f)
12}
13
14pub fn fn_factory<F, Cfg, Srv, Req, Fut, Err>(f: F) -> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
50where
51 F: Fn() -> Fut,
52 Fut: Future<Output = Result<Srv, Err>>,
53 Srv: Service<Req>,
54{
55 FnServiceNoConfig::new(f)
56}
57
58pub fn fn_factory_with_config<F, Fut, Cfg, Srv, Req, Err>(
88 f: F,
89) -> FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
90where
91 F: Fn(Cfg) -> Fut,
92 Fut: Future<Output = Result<Srv, Err>>,
93 Srv: Service<Req>,
94{
95 FnServiceConfig::new(f)
96}
97
98pub struct FnService<F, Fut, Req, Res, Err>
99where
100 F: FnMut(Req) -> Fut,
101 Fut: Future<Output = Result<Res, Err>>,
102{
103 f: F,
104 _t: PhantomData<fn(Req)>,
105}
106
107impl<F, Fut, Req, Res, Err> FnService<F, Fut, Req, Res, Err>
108where
109 F: FnMut(Req) -> Fut,
110 Fut: Future<Output = Result<Res, Err>>,
111{
112 pub(crate) fn new(f: F) -> Self {
113 Self { f, _t: PhantomData }
114 }
115}
116
117impl<F, Fut, Req, Res, Err> Clone for FnService<F, Fut, Req, Res, Err>
118where
119 F: FnMut(Req) -> Fut + Clone,
120 Fut: Future<Output = Result<Res, Err>>,
121{
122 fn clone(&self) -> Self {
123 Self::new(self.f.clone())
124 }
125}
126
127impl<F, Fut, Req, Res, Err> Service<Req> for FnService<F, Fut, Req, Res, Err>
128where
129 F: Fn(Req) -> Fut,
130 Fut: Future<Output = Result<Res, Err>>,
131{
132 type Response = Res;
133 type Error = Err;
134 type Future = Fut;
135
136 crate::always_ready!();
137
138 fn call(&self, req: Req) -> Self::Future {
139 (self.f)(req)
140 }
141}
142
143impl<F, Fut, Req, Res, Err> IntoService<FnService<F, Fut, Req, Res, Err>, Req> for F
144where
145 F: Fn(Req) -> Fut,
146 Fut: Future<Output = Result<Res, Err>>,
147{
148 fn into_service(self) -> FnService<F, Fut, Req, Res, Err> {
149 FnService::new(self)
150 }
151}
152
153pub struct FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
154where
155 F: Fn(Req) -> Fut,
156 Fut: Future<Output = Result<Res, Err>>,
157{
158 f: F,
159 _t: PhantomData<fn(Req, Cfg)>,
160}
161
162impl<F, Fut, Req, Res, Err, Cfg> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
163where
164 F: Fn(Req) -> Fut + Clone,
165 Fut: Future<Output = Result<Res, Err>>,
166{
167 fn new(f: F) -> Self {
168 FnServiceFactory { f, _t: PhantomData }
169 }
170}
171
172impl<F, Fut, Req, Res, Err, Cfg> Clone for FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
173where
174 F: Fn(Req) -> Fut + Clone,
175 Fut: Future<Output = Result<Res, Err>>,
176{
177 fn clone(&self) -> Self {
178 Self::new(self.f.clone())
179 }
180}
181
182impl<F, Fut, Req, Res, Err> Service<Req> for FnServiceFactory<F, Fut, Req, Res, Err, ()>
183where
184 F: Fn(Req) -> Fut + Clone,
185 Fut: Future<Output = Result<Res, Err>>,
186{
187 type Response = Res;
188 type Error = Err;
189 type Future = Fut;
190
191 crate::always_ready!();
192
193 fn call(&self, req: Req) -> Self::Future {
194 (self.f)(req)
195 }
196}
197
198impl<F, Fut, Req, Res, Err, Cfg> ServiceFactory<Req>
199 for FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
200where
201 F: Fn(Req) -> Fut + Clone,
202 Fut: Future<Output = Result<Res, Err>>,
203{
204 type Response = Res;
205 type Error = Err;
206
207 type Config = Cfg;
208 type Service = FnService<F, Fut, Req, Res, Err>;
209 type InitError = ();
210 type Future = Ready<Result<Self::Service, Self::InitError>>;
211
212 fn new_service(&self, _: Cfg) -> Self::Future {
213 ok(FnService::new(self.f.clone()))
214 }
215}
216
217impl<F, Fut, Req, Res, Err, Cfg>
218 IntoServiceFactory<FnServiceFactory<F, Fut, Req, Res, Err, Cfg>, Req> for F
219where
220 F: Fn(Req) -> Fut + Clone,
221 Fut: Future<Output = Result<Res, Err>>,
222{
223 fn into_factory(self) -> FnServiceFactory<F, Fut, Req, Res, Err, Cfg> {
224 FnServiceFactory::new(self)
225 }
226}
227
228pub struct FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
230where
231 F: Fn(Cfg) -> Fut,
232 Fut: Future<Output = Result<Srv, Err>>,
233 Srv: Service<Req>,
234{
235 f: F,
236 _t: PhantomData<fn(Cfg, Req) -> (Fut, Srv, Err)>,
237}
238
239impl<F, Fut, Cfg, Srv, Req, Err> FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
240where
241 F: Fn(Cfg) -> Fut,
242 Fut: Future<Output = Result<Srv, Err>>,
243 Srv: Service<Req>,
244{
245 fn new(f: F) -> Self {
246 FnServiceConfig { f, _t: PhantomData }
247 }
248}
249
250impl<F, Fut, Cfg, Srv, Req, Err> Clone for FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
251where
252 F: Fn(Cfg) -> Fut + Clone,
253 Fut: Future<Output = Result<Srv, Err>>,
254 Srv: Service<Req>,
255{
256 fn clone(&self) -> Self {
257 FnServiceConfig {
258 f: self.f.clone(),
259 _t: PhantomData,
260 }
261 }
262}
263
264impl<F, Fut, Cfg, Srv, Req, Err> ServiceFactory<Req> for FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
265where
266 F: Fn(Cfg) -> Fut,
267 Fut: Future<Output = Result<Srv, Err>>,
268 Srv: Service<Req>,
269{
270 type Response = Srv::Response;
271 type Error = Srv::Error;
272
273 type Config = Cfg;
274 type Service = Srv;
275 type InitError = Err;
276 type Future = Fut;
277
278 fn new_service(&self, cfg: Cfg) -> Self::Future {
279 (self.f)(cfg)
280 }
281}
282
283pub struct FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
285where
286 F: Fn() -> Fut,
287 Srv: Service<Req>,
288 Fut: Future<Output = Result<Srv, Err>>,
289{
290 f: F,
291 _t: PhantomData<fn(Cfg, Req)>,
292}
293
294impl<F, Cfg, Srv, Req, Fut, Err> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
295where
296 F: Fn() -> Fut,
297 Fut: Future<Output = Result<Srv, Err>>,
298 Srv: Service<Req>,
299{
300 fn new(f: F) -> Self {
301 Self { f, _t: PhantomData }
302 }
303}
304
305impl<F, Cfg, Srv, Req, Fut, Err> ServiceFactory<Req>
306 for FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
307where
308 F: Fn() -> Fut,
309 Fut: Future<Output = Result<Srv, Err>>,
310 Srv: Service<Req>,
311{
312 type Response = Srv::Response;
313 type Error = Srv::Error;
314 type Config = Cfg;
315 type Service = Srv;
316 type InitError = Err;
317 type Future = Fut;
318
319 fn new_service(&self, _: Cfg) -> Self::Future {
320 (self.f)()
321 }
322}
323
324impl<F, Cfg, Srv, Req, Fut, Err> Clone for FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
325where
326 F: Fn() -> Fut + Clone,
327 Fut: Future<Output = Result<Srv, Err>>,
328 Srv: Service<Req>,
329{
330 fn clone(&self) -> Self {
331 Self::new(self.f.clone())
332 }
333}
334
335impl<F, Cfg, Srv, Req, Fut, Err>
336 IntoServiceFactory<FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>, Req> for F
337where
338 F: Fn() -> Fut,
339 Fut: Future<Output = Result<Srv, Err>>,
340 Srv: Service<Req>,
341{
342 fn into_factory(self) -> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err> {
343 FnServiceNoConfig::new(self)
344 }
345}
346
347#[cfg(test)]
348mod tests {
349 use core::task::Poll;
350
351 use futures_util::future::lazy;
352
353 use super::*;
354
355 #[actix_rt::test]
356 async fn test_fn_service() {
357 let new_srv = fn_service(|()| ok::<_, ()>("srv"));
358
359 let srv = new_srv.new_service(()).await.unwrap();
360 let res = srv.call(()).await;
361 assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(())));
362 assert!(res.is_ok());
363 assert_eq!(res.unwrap(), "srv");
364 }
365
366 #[actix_rt::test]
367 async fn test_fn_service_service() {
368 let srv = fn_service(|()| ok::<_, ()>("srv"));
369
370 let res = srv.call(()).await;
371 assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(())));
372 assert!(res.is_ok());
373 assert_eq!(res.unwrap(), "srv");
374 }
375
376 #[actix_rt::test]
377 async fn test_fn_service_with_config() {
378 let new_srv = fn_factory_with_config(|cfg: usize| {
379 ok::<_, ()>(fn_service(move |()| ok::<_, ()>(("srv", cfg))))
380 });
381
382 let srv = new_srv.new_service(1).await.unwrap();
383 let res = srv.call(()).await;
384 assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(())));
385 assert!(res.is_ok());
386 assert_eq!(res.unwrap(), ("srv", 1));
387 }
388
389 #[actix_rt::test]
390 async fn test_auto_impl_send() {
391 use alloc::rc::Rc;
392
393 use crate::{map_config, ServiceExt, ServiceFactoryExt};
394
395 let srv_1 = fn_service(|_: Rc<u8>| ok::<_, Rc<u8>>(Rc::new(0u8)));
396
397 let fac_1 = fn_factory_with_config(|_: Rc<u8>| {
398 ok::<_, Rc<u8>>(fn_service(|_: Rc<u8>| ok::<_, Rc<u8>>(Rc::new(0u8))))
399 });
400
401 let fac_2 =
402 fn_factory(|| ok::<_, Rc<u8>>(fn_service(|_: Rc<u8>| ok::<_, Rc<u8>>(Rc::new(0u8)))));
403
404 fn is_send<T: Send + Sync + Clone>(_: &T) {}
405
406 is_send(&fac_1);
407 is_send(&map_config(fac_1.clone(), |_: Rc<u8>| Rc::new(0u8)));
408 is_send(&fac_1.clone().map_err(|_| Rc::new(0u8)));
409 is_send(&fac_1.clone().map(|_| Rc::new(0u8)));
410 is_send(&fac_1.clone().map_init_err(|_| Rc::new(0u8)));
411 is_send(&fac_1.new_service(Rc::new(0u8)).await.unwrap());
414
415 is_send(&fac_2);
416 is_send(&fac_2.new_service(Rc::new(0u8)).await.unwrap());
417
418 is_send(&srv_1);
419 is_send(&ServiceExt::map(srv_1.clone(), |_| Rc::new(0u8)));
420 is_send(&ServiceExt::map_err(srv_1.clone(), |_| Rc::new(0u8)));
421 }
424}