1use std::{convert::Infallible, future::Future};
12
13use futures::future::BoxFuture;
14use rinf::{DartSignal, RustSignal};
15
16use crate::{extractor::FromRequest, into_response::IntoResponse};
17
18pub struct HandlerService<H, T, S> {
20 handler: H,
21 state: S,
22 _phantom: std::marker::PhantomData<fn() -> T>,
23}
24
25impl<H, T, S> Clone for HandlerService<H, T, S>
26where
27 H: Clone,
28 S: Clone,
29{
30 fn clone(&self) -> Self {
31 Self {
32 handler: self.handler.clone(),
33 state: self.state.clone(),
34 _phantom: std::marker::PhantomData,
35 }
36 }
37}
38
39impl<H, T, S> HandlerService<H, T, S>
40where
41 H: Clone,
42 S: Clone,
43{
44 pub fn new(handler: H, state: S) -> Self {
46 Self {
47 handler,
48 state,
49 _phantom: std::marker::PhantomData,
50 }
51 }
52}
53
54impl<H, T, S> tower::Service<H::Signal> for HandlerService<H, T, S>
55where
56 H: Handler<T, S>,
57 H::Future: Send + 'static,
58 S: Clone,
59{
60 type Error = Infallible;
61 type Future = BoxFuture<'static, Result<(), Infallible>>;
62 type Response = ();
63
64 fn poll_ready(
65 &mut self,
66 _cx: &mut std::task::Context<'_>,
67 ) -> std::task::Poll<Result<(), Self::Error>> {
68 std::task::Poll::Ready(Ok(()))
69 }
70
71 fn call(&mut self, signal: H::Signal) -> Self::Future {
72 let future = self.handler.clone().call(signal, self.state.clone());
73 Box::pin(async move {
74 future.await;
75 Ok(())
76 })
77 }
78}
79
80macro_rules! impl_handler {
81 (
82 [$($arg:ident),*], $last:ident
83 ) => {
84 #[allow(non_snake_case)]
85 impl<F, Fut, R $(,$arg)*, $last, S> Handler<($($arg,)* $last,), S> for F
87 where
88 F: FnOnce($($arg,)* $last) -> Fut + Clone + Send + Sync + 'static,
89 Fut: Future<Output = R> + Send + 'static,
90 S: Clone + Send + Sync + 'static,
91 R: IntoResponse + Send + 'static,
92 $(
93 $arg: FromRequest<$last, S> + Send + 'static,
94 )*
95 $last: DartSignal + Send + Sync + 'static,
96 {
97 type Signal = $last;
98 type Future = BoxFuture<'static, ()>;
99
100
101 #[cfg_attr(feature = "tracing", tracing::instrument(skip_all, level = "info"))]
102 fn call(self, signal: $last, state: S) -> Self::Future {
103 Box::pin(async move {
104 #[allow(unused_variables)]
106 let _ = &state;
107
108 $(
110 let $arg = $arg::from_request(&signal, &state).await;
111 )*
112
113 let result = self($($arg,)* signal).await.into_response();
115
116 result.send_signal_to_dart();
118 })
119 }
120 }
121 };
122}
123
124pub trait Handler<T, S>: Clone + Send + Sized {
141 type Signal: DartSignal + Send + Sync + 'static;
143
144 type Future: Future<Output = ()> + Send + 'static;
146
147 fn call(self, signal: Self::Signal, state: S) -> Self::Future;
149
150 fn layer<L>(self, layer: L) -> Layered<L, Self, T, S>
152 where
153 L: tower::Layer<HandlerService<Self, T, S>> + Clone + Send + 'static,
154 L::Service: tower::Service<Self::Signal, Response = (), Error = Infallible>
155 + Clone
156 + Send
157 + 'static,
158 S: Clone + Send + Sync + 'static,
159 {
160 Layered {
161 layer,
162 handler: self,
163 _phantom: std::marker::PhantomData,
164 }
165 }
166
167 fn with_state(self, state: S) -> HandlerService<Self, T, S>
170 where
171 S: Clone + Send + Sync + 'static,
172 {
173 HandlerService::new(self, state)
174 }
175}
176
177pub struct Layered<L, H, T, S> {
183 layer: L,
184 handler: H,
185 _phantom: std::marker::PhantomData<fn() -> (T, S)>,
186}
187
188impl<L, H, T, S> Clone for Layered<L, H, T, S>
189where
190 L: Clone,
191 H: Clone,
192{
193 fn clone(&self) -> Self {
194 Self {
195 layer: self.layer.clone(),
196 handler: self.handler.clone(),
197 _phantom: std::marker::PhantomData,
198 }
199 }
200}
201
202impl<L, H, T, S> Handler<T, S> for Layered<L, H, T, S>
203where
204 H: Handler<T, S>,
205 L: tower::Layer<HandlerService<H, T, S>> + Clone + Send + 'static,
206 L::Service:
207 tower::Service<H::Signal, Response = (), Error = Infallible> + Clone + Send + 'static,
208 <L::Service as tower::Service<H::Signal>>::Future: Send + 'static,
209 S: Clone + Send + Sync + 'static,
210 T: Send + Sync + 'static,
211{
212 type Future = BoxFuture<'static, ()>;
213 type Signal = H::Signal;
214
215 fn call(self, signal: Self::Signal, state: S) -> Self::Future {
216 let svc = self.handler.with_state(state);
217 let svc = self.layer.layer(svc);
218
219 Box::pin(async move {
220 use tower::ServiceExt;
221 let _ = svc.oneshot(signal).await;
222 })
223 }
224}
225
226pub trait HandlerWithoutStateExt<T>: Handler<T, ()> + Sized {
228 fn into_service(self) -> HandlerService<Self, T, ()> {
230 Handler::with_state(self, ())
231 }
232}
233
234impl<H, T> HandlerWithoutStateExt<T> for H where H: Handler<T, ()> {}
235
236impl_handler!([], T1);
237impl_handler!([T1], T2);
238impl_handler!([T1, T2], T3);
239impl_handler!([T1, T2, T3], T4);
240impl_handler!([T1, T2, T3, T4], T5);
241impl_handler!([T1, T2, T3, T4, T5], T6);
242impl_handler!([T1, T2, T3, T4, T5, T6], T7);
243impl_handler!([T1, T2, T3, T4, T5, T6, T7], T8);
244impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8], T9);
245impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9], T10);
246impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], T11);
247impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], T12);
248impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], T13);
249impl_handler!(
250 [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13],
251 T14
252);
253impl_handler!(
254 [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14],
255 T15
256);
257impl_handler!(
258 [
259 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15
260 ],
261 T16
262);
263
264#[cfg(all(test, feature = "test-helpers"))]
265mod tests {
266 use std::sync::{
267 Arc,
268 Mutex,
269 atomic::{AtomicUsize, Ordering},
270 };
271
272 use serial_test::serial;
273 use tower::ServiceExt;
274
275 use super::*;
276 use crate::{
277 State,
278 test_helpers::{EmptySignal, Signal, assert_handler},
279 };
280
281 #[tokio::test]
283 #[allow(unused_must_use)]
284 async fn handler_signatures_compile() {
285 async fn empty_handler() {}
286 async fn signal_handler(_: Signal) {}
287 async fn stateful_handler(State(_): State<String>, _: Signal) {}
288 async fn response_handler(State(_): State<String>, _: Signal) -> Option<()> {
289 None
290 }
291
292 assert_handler::<_, (), _>(empty_handler);
293 assert_handler::<_, (), _>(signal_handler);
294 assert_handler(stateful_handler);
295 assert_handler(response_handler);
296 }
297
298 #[tokio::test]
299 async fn into_service_converts_stateless_handler() {
300 let counter = Arc::new(AtomicUsize::new(0));
301 let counter_clone = Arc::clone(&counter);
302
303 let handler = move || {
304 let counter = Arc::clone(&counter_clone);
305 async move {
306 counter.fetch_add(1, Ordering::SeqCst);
307 }
308 };
309
310 let service = handler.into_service();
311 service.oneshot(EmptySignal).await.unwrap();
312
313 assert_eq!(counter.load(Ordering::SeqCst), 1);
314 }
315
316 #[tokio::test]
317 #[serial]
318 async fn handler_processes_signal() {
319 let received = Arc::new(Mutex::new(String::new()));
320 let received_clone = Arc::clone(&received);
321
322 let handler = move |signal: Signal| {
323 let received = Arc::clone(&received_clone);
324 async move {
325 *received.lock().unwrap() = signal.message;
326 }
327 };
328
329 handler.call(Signal::new("test"), ()).await;
330 assert_eq!(*received.lock().unwrap(), "test");
331 }
332}