1use super::{Ctx, Service, ServiceFactory, util};
2
3#[derive(Debug, Clone)]
4pub struct Then<A, B> {
8 svc1: A,
9 svc2: B,
10}
11
12impl<A, B> Then<A, B> {
13 pub(crate) fn new(svc1: A, svc2: B) -> Then<A, B> {
15 Self { svc1, svc2 }
16 }
17}
18
19impl<A, B, St, Req> Service<St, Req> for Then<A, B>
20where
21 A: Service<St, Req>,
22 B: Service<St, Result<A::Res, A::Error>, Error = A::Error>,
23{
24 type Res = B::Res;
25 type Error = B::Error;
26
27 #[inline]
28 async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<B::Res, B::Error> {
29 ctx.call(&self.svc2, ctx.call(&self.svc1, req).await).await
30 }
31
32 #[inline]
33 async fn ready(&self, ctx: Ctx<'_, Self, St>) -> Result<(), Self::Error> {
34 util::ready(&self.svc1, &self.svc2, ctx).await
35 }
36
37 #[inline]
38 async fn shutdown(&self, ctx: Ctx<'_, Self, St>) {
39 util::shutdown(&self.svc1, &self.svc2, ctx).await;
40 }
41}
42
43#[derive(Debug, Clone)]
44pub struct ThenFactory<A, B> {
46 svc1: A,
47 svc2: B,
48}
49
50impl<A, B> ThenFactory<A, B> {
51 pub(crate) fn new(svc1: A, svc2: B) -> Self {
53 Self { svc1, svc2 }
54 }
55}
56
57impl<A, B, St, Req> ServiceFactory<St, Req> for ThenFactory<A, B>
58where
59 A: ServiceFactory<St, Req>,
60 B: ServiceFactory<St, Result<A::Res, A::Error>, Error = A::Error, InitError = A::InitError>,
61{
62 type Res = B::Res;
63 type Error = A::Error;
64
65 type Service = Then<A::Service, B::Service>;
66 type InitError = A::InitError;
67
68 async fn create(&self, st: &St) -> Result<Self::Service, Self::InitError> {
69 Ok(Then {
70 svc1: self.svc1.create(st).await?,
71 svc2: self.svc2.create(st).await?,
72 })
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use std::{cell::Cell, rc::Rc};
79
80 use crate::{Ctx, Service, factory, fn_factory, service};
81
82 #[derive(Clone)]
83 struct Srv1(Rc<Cell<usize>>, Rc<Cell<usize>>);
84
85 impl Service<(), Result<&'static str, &'static str>> for Srv1 {
86 type Res = &'static str;
87 type Error = ();
88
89 async fn ready(&self, _: Ctx<'_, Self>) -> Result<(), Self::Error> {
90 self.0.set(self.0.get() + 1);
91 Ok(())
92 }
93
94 async fn call(
95 &self,
96 req: Result<&'static str, &'static str>,
97 _: Ctx<'_, Self>,
98 ) -> Result<&'static str, ()> {
99 match req {
100 Ok(msg) => Ok(msg),
101 Err(_) => Err(()),
102 }
103 }
104
105 async fn shutdown(&self, _: Ctx<'_, Self, ()>) {
106 self.1.set(self.1.get() + 1);
107 }
108 }
109
110 #[derive(Clone)]
111 struct Srv2(Rc<Cell<usize>>, Rc<Cell<usize>>);
112
113 impl Service<(), Result<&'static str, ()>> for Srv2 {
114 type Res = (&'static str, &'static str);
115 type Error = ();
116
117 async fn ready(&self, _: Ctx<'_, Self>) -> Result<(), Self::Error> {
118 self.0.set(self.0.get() + 1);
119 Ok(())
120 }
121
122 async fn call(
123 &self,
124 req: Result<&'static str, ()>,
125 _: Ctx<'_, Self>,
126 ) -> Result<Self::Res, ()> {
127 match req {
128 Ok(msg) => Ok((msg, "ok")),
129 Err(()) => Ok(("srv2", "err")),
130 }
131 }
132
133 async fn shutdown(&self, _: Ctx<'_, Self, ()>) {
134 self.1.set(self.1.get() + 1);
135 }
136 }
137
138 #[ntex::test]
139 async fn test_ready() {
140 let cnt = Rc::new(Cell::new(0));
141 let cnt_sht = Rc::new(Cell::new(0));
142 let srv = service(Srv1(cnt.clone(), cnt_sht.clone()))
143 .then(Srv2(cnt.clone(), cnt_sht.clone()))
144 .pipeline(());
145 let res = srv.ready().await;
146 assert_eq!(res, Ok(()));
147 assert_eq!(cnt.get(), 2);
148
149 srv.shutdown().await;
150 assert_eq!(cnt_sht.get(), 2);
151 }
152
153 #[ntex::test]
154 async fn test_call() {
155 let cnt = Rc::new(Cell::new(0));
156 let srv = service(Srv1(cnt.clone(), Rc::new(Cell::new(0))))
157 .then(Srv2(cnt, Rc::new(Cell::new(0))))
158 .clone()
159 .pipeline(());
160
161 let res = srv.call(Ok("srv1")).await;
162 assert!(res.is_ok());
163 assert_eq!(res.unwrap(), ("srv1", "ok"));
164
165 let res = srv.call(Err("srv")).await;
166 assert!(res.is_ok());
167 assert_eq!(res.unwrap(), ("srv2", "err"));
168 }
169
170 #[ntex::test]
171 async fn test_factory() {
172 let cnt = Rc::new(Cell::new(0));
173 let cnt2 = cnt.clone();
174 let blank = fn_factory(move |(): &_| {
175 let cnt = cnt2.clone();
176 async move { Ok::<_, ()>(Srv1(cnt, Rc::new(Cell::new(0)))) }
177 });
178 let factory = factory(blank)
179 .then(fn_factory(move |(): &()| {
180 let cnt = cnt.clone();
181 async move { Ok(Srv2(cnt.clone(), Rc::new(Cell::new(0)))) }
182 }))
183 .clone();
184 let srv = factory.pipeline(()).await.unwrap();
185 let res = srv.call(Ok("srv1")).await;
186 assert!(res.is_ok());
187 assert_eq!(res.unwrap(), ("srv1", "ok"));
188
189 let res = srv.call(Err("srv")).await;
190 assert!(res.is_ok());
191 assert_eq!(res.unwrap(), ("srv2", "err"));
192 }
193}