faucet_server/server/
onion.rs

1use 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}