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