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