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