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