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