Skip to main content

ntex_service/
pl_factory.rs

1use std::{fmt, rc::Rc};
2
3use crate::{ServiceFactory, pipeline::Pipeline, util::BoxFuture};
4
5/// Factory for a service pipeline.
6pub struct PipelineFactory<St, Req, Res, Err, InitErr> {
7    f: Rc<dyn Fn(St) -> BoxFuture<'static, Result<Pipeline<Req, Res, Err>, InitErr>>>,
8}
9
10impl<St, Req, Res, Err, InitErr> PipelineFactory<St, Req, Res, Err, InitErr> {
11    /// Creates a pipeline factory from a service factory.
12    pub fn new<Sf>(sf: Sf) -> Self
13    where
14        Sf: ServiceFactory<St, Req, Res = Res, Error = Err, InitError = InitErr> + 'static,
15        St: 'static,
16        Req: 'static,
17        Res: 'static,
18        Err: 'static,
19    {
20        let sf = Rc::new(sf);
21        Self {
22            f: Rc::new(move |st: St| {
23                let sf = sf.clone();
24                Box::pin(async move {
25                    let svc = sf.create(&st).await?;
26                    Ok(Pipeline::new(st, svc))
27                })
28            }),
29        }
30    }
31
32    /// Creates a service with `st` and wraps both in a [`Pipeline`].
33    pub async fn create(&self, st: St) -> Result<Pipeline<Req, Res, Err>, InitErr> {
34        (self.f)(st).await
35    }
36}
37
38impl<St, Req, Res, Err, InitErr> Clone for PipelineFactory<St, Req, Res, Err, InitErr> {
39    fn clone(&self) -> Self {
40        PipelineFactory { f: self.f.clone() }
41    }
42}
43
44impl<St, Req, Res, Err, InitErr> fmt::Debug for PipelineFactory<St, Req, Res, Err, InitErr> {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        f.debug_struct("PipelineFactory").finish()
47    }
48}