faucet_server/server/
onion.rs1use std::net::IpAddr;
2
3pub trait Service<Request>: Send + Sync {
4 type Response;
5 type Error;
6 fn call(
7 &self,
8 req: Request,
9 ip_addr: Option<IpAddr>,
10 ) -> impl std::future::Future<Output = Result<Self::Response, Self::Error>>;
11}
12
13pub trait Layer<S> {
14 type Service;
15 fn layer(&self, inner: S) -> Self::Service;
16}
17
18pub struct ServiceBuilder<S> {
19 service: S,
20}
21
22impl<S> ServiceBuilder<S> {
23 pub fn new(service: S) -> Self {
24 ServiceBuilder { service }
25 }
26 pub fn layer<L>(self, layer: L) -> ServiceBuilder<L::Service>
27 where
28 L: Layer<S>,
29 {
30 ServiceBuilder::new(layer.layer(self.service))
31 }
32 pub fn build(self) -> S {
33 self.service
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[tokio::test]
42 async fn basic_service_response() {
43 struct Svc;
44
45 impl Service<()> for Svc {
46 type Response = String;
47 type Error = ();
48 async fn call(&self, _: (), _: Option<IpAddr>) -> Result<Self::Response, Self::Error> {
49 Ok("Hello, world!".to_string())
50 }
51 }
52
53 let svc = ServiceBuilder::new(Svc).build();
54
55 assert_eq!(svc.call((), None).await.unwrap(), "Hello, world!");
56 }
57
58 #[tokio::test]
59 async fn basic_service_middleware() {
60 struct Svc;
61
62 impl Service<&'static str> for Svc {
63 type Response = String;
64 type Error = ();
65 async fn call(
66 &self,
67 _: &'static str,
68 _: Option<IpAddr>,
69 ) -> Result<Self::Response, Self::Error> {
70 Ok("Hello, world!".to_string())
71 }
72 }
73
74 struct GoodByeService<S> {
75 inner: S,
76 }
77
78 impl<S> Service<&'static str> for GoodByeService<S>
79 where
80 S: Service<&'static str, Response = String, Error = ()>,
81 {
82 type Response = String;
83 type Error = ();
84 async fn call(
85 &self,
86 req: &'static str,
87 _: Option<IpAddr>,
88 ) -> Result<Self::Response, Self::Error> {
89 if req == "Goodbye" {
90 Ok("Goodbye, world!".to_string())
91 } else {
92 self.inner.call(req, None).await
93 }
94 }
95 }
96
97 struct GoodByeLayer;
98
99 impl<S> Layer<S> for GoodByeLayer {
100 type Service = GoodByeService<S>;
101 fn layer(&self, inner: S) -> Self::Service {
102 GoodByeService { inner }
103 }
104 }
105
106 let svc = ServiceBuilder::new(Svc).layer(GoodByeLayer).build();
107
108 assert_eq!(svc.call("Goodbye", None).await.unwrap(), "Goodbye, world!");
109 assert_eq!(svc.call("Hello", None).await.unwrap(), "Hello, world!");
110 }
111
112 #[tokio::test]
113 async fn multiple_layer_middleware() {
114 struct Svc;
115
116 impl Service<&'static str> for Svc {
117 type Response = String;
118 type Error = ();
119 async fn call(
120 &self,
121 _: &'static str,
122 _: Option<IpAddr>,
123 ) -> Result<Self::Response, Self::Error> {
124 Ok("Hello, world!".to_string())
125 }
126 }
127
128 struct GoodByeService<S> {
129 inner: S,
130 }
131
132 impl<S> Service<&'static str> for GoodByeService<S>
133 where
134 S: Service<&'static str, Response = String, Error = ()>,
135 {
136 type Response = String;
137 type Error = ();
138 async fn call(
139 &self,
140 req: &'static str,
141 _: Option<IpAddr>,
142 ) -> Result<Self::Response, Self::Error> {
143 if req == "Goodbye" {
144 Ok("Goodbye, world!".to_string())
145 } else {
146 self.inner.call(req, None).await
147 }
148 }
149 }
150
151 struct GoodByeLayer;
152
153 impl<S> Layer<S> for GoodByeLayer {
154 type Service = GoodByeService<S>;
155 fn layer(&self, inner: S) -> Self::Service {
156 GoodByeService { inner }
157 }
158 }
159
160 struct HowAreYouService<S> {
161 inner: S,
162 }
163
164 impl<S> Service<&'static str> for HowAreYouService<S>
165 where
166 S: Service<&'static str, Response = String, Error = ()>,
167 {
168 type Response = String;
169 type Error = ();
170 async fn call(
171 &self,
172 req: &'static str,
173 _: Option<IpAddr>,
174 ) -> Result<Self::Response, Self::Error> {
175 if req == "How are you?" {
176 Ok("I'm fine, thank you!".to_string())
177 } else {
178 self.inner.call(req, None).await
179 }
180 }
181 }
182
183 struct HowAreYouLayer;
184
185 impl<S> Layer<S> for HowAreYouLayer {
186 type Service = HowAreYouService<S>;
187 fn layer(&self, inner: S) -> Self::Service {
188 HowAreYouService { inner }
189 }
190 }
191
192 let svc = ServiceBuilder::new(Svc)
193 .layer(GoodByeLayer)
194 .layer(HowAreYouLayer)
195 .build();
196
197 assert_eq!(svc.call("Goodbye", None).await.unwrap(), "Goodbye, world!");
198 assert_eq!(svc.call("Hello", None).await.unwrap(), "Hello, world!");
199 assert_eq!(
200 svc.call("How are you?", None).await.unwrap(),
201 "I'm fine, thank you!"
202 );
203 }
204}