1#![allow(clippy::type_complexity)]
2
3#[cfg(not(feature = "std"))]
4extern crate alloc;
5
6use core::{future::Future, pin::Pin};
7
8#[cfg(not(feature = "std"))]
9use alloc::{boxed::Box, sync::Arc};
10#[cfg(feature = "std")]
11use std::sync::Arc;
12
13use crate::Frame;
14
15pub type HandlerFuture = Pin<Box<dyn Future<Output = Result<Option<Frame>, crate::TightBeamError>> + Send>>;
16pub type SharedHandler = Arc<dyn Fn(Frame) -> HandlerFuture + Send + Sync>;
17
18pub fn into_shared_handler<F, Fut>(handler: F) -> SharedHandler
19where
20 F: Fn(Frame) -> Fut + Send + Sync + Clone + 'static,
21 Fut: Future<Output = Result<Option<Frame>, crate::TightBeamError>> + Send + 'static,
22{
23 let handler = Arc::new(handler);
24 Arc::new(move |frame: Frame| -> HandlerFuture {
25 let handler = ::std::sync::Arc::clone(&handler);
26 Box::pin(async move { handler(frame).await })
27 })
28}
29
30#[cfg(feature = "tokio")]
31#[macro_export]
32macro_rules! __tightbeam_server_protocol_handle {
33 ($protocol:path, $listener:expr, $handler:expr) => {{
34 let __listener = $listener;
35 $crate::macros::server::server_runtime::rt::spawn(async move {
36 let __error_tx = $crate::macros::server::server_runtime::rt::empty_error_channel();
37 let __ok_tx = $crate::macros::server::server_runtime::rt::empty_ok_channel();
38 $crate::server!(@async_loop $protocol, __listener, $handler, __error_tx, __ok_tx,)
39 })
40 }};
41
42 ($protocol:path, $listener:expr, assertions: $assertions:expr, ($param1:ident, $param2:ident, $handler_body:expr)) => {{
43 #[allow(unused_imports)]
44 use $crate::trace::TraceCollector;
45
46 let __listener = $listener;
47 let __assertions = $assertions;
48 $crate::macros::server::server_runtime::rt::spawn(async move {
49 let __error_tx = $crate::macros::server::server_runtime::rt::empty_error_channel();
50 let __ok_tx = $crate::macros::server::server_runtime::rt::empty_ok_channel();
51 $crate::server!(@async_loop_assertions $protocol, __listener, __assertions, ($param1, $param2, $handler_body), __error_tx, __ok_tx,)
52 })
53 }};
54}
55
56#[cfg(all(not(feature = "tokio"), feature = "std"))]
57#[macro_export]
58macro_rules! __tightbeam_server_protocol_handle {
59 ($protocol:path, $listener:expr, $handler:expr) => {{
60 let __listener = $listener;
61 std::thread::spawn(move || {
62 $crate::server!(@sync_loop $protocol, __listener, $handler,)
63 })
64 }};
65}
66
67#[cfg(not(any(feature = "tokio", feature = "std")))]
68#[macro_export]
69macro_rules! __tightbeam_server_protocol_handle {
70 ($protocol:path, $listener:expr, $handler:expr) => {
71 compile_error!("server!(protocol …) requires tightbeam to be built with either the `tokio` or `std` feature");
72 };
73}
74
75#[cfg(feature = "tokio")]
76#[macro_export]
77macro_rules! __tightbeam_server_protocol_bind_handle {
78 ($protocol:path, $addr:expr, $handler:expr) => {{
79 let (listener, _) = <$protocol as $crate::transport::Protocol>::bind($addr).await?;
80 let __server = <$protocol>::from(listener);
81 $crate::macros::server::server_runtime::rt::spawn(async move {
82 let __error_tx = $crate::macros::server::server_runtime::rt::empty_error_channel();
83 let __ok_tx = $crate::macros::server::server_runtime::rt::empty_ok_channel();
84 $crate::server!(@async_loop $protocol, __server, $handler, __error_tx, __ok_tx,)
85 })
86 }};
87}
88
89#[cfg(all(not(feature = "tokio"), feature = "std"))]
90#[macro_export]
91macro_rules! __tightbeam_server_protocol_bind_handle {
92 ($protocol:path, $addr:expr, $handler:expr) => {{
93 let (listener, _) = <$protocol as $crate::transport::Protocol>::bind($addr)?;
94 let __server = <$protocol>::from(listener);
95 std::thread::spawn(move || {
96 $crate::server!(@sync_loop $protocol, __server, $handler,)
97 })
98 }};
99}
100
101#[cfg(not(any(feature = "tokio", feature = "std")))]
102#[macro_export]
103macro_rules! __tightbeam_server_protocol_bind_handle {
104 ($protocol:path, $addr:expr, $handler:expr) => {
105 compile_error!(
106 "server!(protocol …) with `bind` requires tightbeam to be built with either the `tokio` or `std` feature"
107 );
108 };
109}
110
111#[cfg(feature = "tokio")]
112#[macro_export]
113macro_rules! __tightbeam_server_protocol_policies_handle {
114 ($protocol:path, $listener:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $handler:expr) => {{
115 let __listener = $listener;
116 $crate::macros::server::server_runtime::rt::spawn(async move {
117 let __error_tx = $crate::macros::server::server_runtime::rt::empty_error_channel();
118 let __ok_tx = $crate::macros::server::server_runtime::rt::empty_ok_channel();
119 $crate::server!(@async_loop $protocol, __listener, $handler, __error_tx, __ok_tx, $($policy_name: [ $( $policy_expr ),* ]),*)
120 })
121 }};
122}
123
124#[cfg(all(not(feature = "tokio"), feature = "std"))]
125#[macro_export]
126macro_rules! __tightbeam_server_protocol_policies_handle {
127 ($protocol:path, $listener:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $handler:expr) => {{
128 let __listener = $listener;
129 std::thread::spawn(move || {
130 $crate::server!(@sync_loop $protocol, __listener, $handler, $($policy_name: [ $( $policy_expr ),* ]),*)
131 })
132 }};
133}
134
135#[cfg(not(any(feature = "tokio", feature = "std")))]
136#[macro_export]
137macro_rules! __tightbeam_server_protocol_policies_handle {
138 ($protocol:path, $listener:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $handler:expr) => {
139 compile_error!(
140 "server!(protocol …, policies: …) requires tightbeam to be built with either the `tokio` or `std` feature"
141 );
142 };
143}
144
145#[cfg(feature = "tokio")]
146#[macro_export]
147macro_rules! __tightbeam_server_protocol_policies_assertions_handle {
148 ($protocol:path, $listener:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $assertions:expr, ($param1:ident, $param2:ident, $handler_body:expr)) => {{
149 #[allow(unused_imports)]
150 use $crate::trace::TraceCollector;
151
152 let __listener = $listener;
153 let __assertions = $assertions;
154 $crate::macros::server::server_runtime::rt::spawn(async move {
155 let __error_tx = $crate::macros::server::server_runtime::rt::empty_error_channel();
156 let __ok_tx = $crate::macros::server::server_runtime::rt::empty_ok_channel();
157 $crate::server!(@async_loop_assertions $protocol, __listener, __assertions, ($param1, $param2, $handler_body), __error_tx, __ok_tx, $($policy_name: [ $( $policy_expr ),* ]),*)
158 })
159 }};
160}
161
162#[cfg(all(not(feature = "tokio"), feature = "std"))]
163#[macro_export]
164macro_rules! __tightbeam_server_protocol_policies_assertions_handle {
165 ($protocol:path, $listener:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $assertions:expr, ($param1:ident, $param2:ident, $handler_body:expr)) => {{
166 compile_error!("server!(protocol …, policies: …, assertions: …) requires the `tokio` feature");
167 }};
168}
169
170#[cfg(not(any(feature = "tokio", feature = "std")))]
171#[macro_export]
172macro_rules! __tightbeam_server_protocol_policies_assertions_handle {
173 ($protocol:path, $listener:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $assertions:expr, ($param1:ident, $param2:ident, $handler_body:expr)) => {{
174 compile_error!(
175 "server!(protocol …, policies: …, assertions: …) requires tightbeam to be built with either the `tokio` or `std` feature"
176 );
177 }};
178}
179
180#[cfg(feature = "tokio")]
181#[macro_export]
182macro_rules! __tightbeam_server_protocol_channels_handle {
183 ($protocol:path, $listener:expr, $error_tx:expr, $ok_tx:expr, $handler:expr) => {{
184 let __listener = $listener;
185 $crate::macros::server::server_runtime::rt::spawn(async move {
186 let __error_tx = Some($error_tx);
187 let __ok_tx = Some($ok_tx);
188 $crate::server!(@async_loop $protocol, __listener, $handler, __error_tx, __ok_tx,)
189 })
190 }};
191}
192
193#[cfg(all(not(feature = "tokio"), feature = "std"))]
194#[macro_export]
195macro_rules! __tightbeam_server_protocol_channels_handle {
196 ($protocol:path, $listener:expr, $error_tx:expr, $ok_tx:expr, $handler:expr) => {{
197 let __listener = $listener;
198 let _ = ($error_tx, $ok_tx);
199 std::thread::spawn(move || {
200 $crate::server!(@sync_loop $protocol, __listener, $handler,)
201 })
202 }};
203}
204
205#[cfg(not(any(feature = "tokio", feature = "std")))]
206#[macro_export]
207macro_rules! __tightbeam_server_protocol_channels_handle {
208 ($protocol:path, $listener:expr, $error_tx:expr, $ok_tx:expr, $handler:expr) => {
209 let _ = ($error_tx, $ok_tx);
210 compile_error!(
211 "server!(protocol …, channels: …) requires tightbeam to be built with either the `tokio` or `std` feature"
212 );
213 };
214}
215
216#[cfg(feature = "tokio")]
217#[macro_export]
218macro_rules! __tightbeam_server_protocol_channels_policies_handle {
219 ($protocol:path, $listener:expr, $error_tx:expr, $ok_tx:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $handler:expr) => {{
220 let __listener = $listener;
221 $crate::macros::server::server_runtime::rt::spawn(async move {
222 let __error_tx = Some($error_tx);
223 let __ok_tx = Some($ok_tx);
224 $crate::server!(@async_loop $protocol, __listener, $handler, __error_tx, __ok_tx, $($policy_name: [ $( $policy_expr ),* ]),*)
225 })
226 }};
227}
228
229#[cfg(all(not(feature = "tokio"), feature = "std"))]
230#[macro_export]
231macro_rules! __tightbeam_server_protocol_channels_policies_handle {
232 ($protocol:path, $listener:expr, $error_tx:expr, $ok_tx:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $handler:expr) => {{
233 let __listener = $listener;
234 let _ = ($error_tx, $ok_tx);
235 std::thread::spawn(move || {
236 $crate::server!(@sync_loop $protocol, __listener, $handler, $($policy_name: [ $( $policy_expr ),* ]),*)
237 })
238 }};
239}
240
241#[cfg(not(any(feature = "tokio", feature = "std")))]
242#[macro_export]
243macro_rules! __tightbeam_server_protocol_channels_policies_handle {
244 ($protocol:path, $listener:expr, $error_tx:expr, $ok_tx:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $handler:expr) => {
245 let _ = ($error_tx, $ok_tx);
246 compile_error!(
247 "server!(protocol …, channels: …) requires tightbeam to be built with either the `tokio` or `std` feature"
248 );
249 };
250}
251
252#[cfg(feature = "tokio")]
253#[macro_export]
254macro_rules! __tightbeam_server_protocol_bind_policies_handle {
255 ($protocol:path, $addr:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $handler:expr) => {{
256 let (listener, _) = <$protocol as $crate::transport::Protocol>::bind($addr).await?;
257 let __server = <$protocol>::from(listener);
258 $crate::macros::server::server_runtime::rt::spawn(async move {
259 let __error_tx = $crate::macros::server::server_runtime::rt::empty_error_channel();
260 let __ok_tx = $crate::macros::server::server_runtime::rt::empty_ok_channel();
261 $crate::server!(@async_loop $protocol, __server, $handler, __error_tx, __ok_tx, $($policy_name: [ $( $policy_expr ),* ]),*)
262 })
263 }};
264}
265
266#[cfg(all(not(feature = "tokio"), feature = "std"))]
267#[macro_export]
268macro_rules! __tightbeam_server_protocol_bind_policies_handle {
269 ($protocol:path, $addr:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $handler:expr) => {{
270 let (listener, _) = <$protocol as $crate::transport::Protocol>::bind($addr)?;
271 let __server = <$protocol>::from(listener);
272 std::thread::spawn(move || {
273 $crate::server!(@sync_loop $protocol, __server, $handler, $($policy_name: [ $( $policy_expr ),* ]),*)
274 })
275 }};
276}
277
278#[cfg(not(any(feature = "tokio", feature = "std")))]
279#[macro_export]
280macro_rules! __tightbeam_server_protocol_bind_policies_handle {
281 ($protocol:path, $addr:expr, [$($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?], $handler:expr) => {
282 compile_error!("server!(protocol …, policies: …) with `bind` requires tightbeam to be built with either the `tokio` or `std` feature");
283 };
284}
285
286#[cfg(any(feature = "tokio", feature = "std"))]
290pub mod server_runtime {
291 pub mod rt {
293 pub use crate::runtime::rt::*;
294
295 use crate::transport::error::TransportError;
296
297 pub type ErrorSender = crate::runtime::rt::Sender<TransportError>;
299
300 pub type OkSender = crate::runtime::rt::Sender<()>;
302
303 #[allow(dead_code)]
305 pub fn empty_error_channel() -> Option<ErrorSender> {
306 None
307 }
308
309 #[allow(dead_code)]
311 pub fn empty_ok_channel() -> Option<OkSender> {
312 None
313 }
314 }
315}
316
317#[macro_export]
318macro_rules! server {
319 (@apply_policy $transport:ident, $policy_name:ident, [ $( $policy_expr:expr ),* $(,)? ]) => {{
320 $(
321 $transport = $crate::server!(@apply_one_policy $transport, $policy_name, $policy_expr);
322 )*
323 }};
324
325 (@apply_one_policy $transport:ident, $other:ident, $policy_expr:expr) => {{
327 $transport.$other($policy_expr)
328 }};
329
330 (@sync_loop_body $protocol:path, $listener:ident, $handler:ident, $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?) => {{
331 loop {
332 match $listener.accept() {
333 Ok((mut __transport, _addr)) => {
334 $(
335 $(
336 __transport = $crate::server!(@apply_one_policy __transport, $policy_name, $policy_expr);
337 )*
338 )*
339 let __handler_clone = ::std::sync::Arc::clone(&$handler);
340 #[allow(unused_imports)]
341 use $crate::transport::MessageCollector;
342 $crate::macros::server::server_runtime::rt::spawn(move || {
343 let mut __transport = __transport;
344 loop {
345 let (frame, status) = match $crate::macros::server::server_runtime::rt::block_on(__transport.collect_message()) {
347 Ok(result) => result,
348 Err(err) => {
349 break;
350 }
351 };
352
353 let response = if status == $crate::policy::TransitStatus::Accepted {
355 $crate::macros::server::server_runtime::rt::block_on((__handler_clone)(frame))
356 } else {
357 None
358 };
359
360 match $crate::macros::server::server_runtime::rt::block_on(__transport.send_response(status, response)) {
362 Ok(()) => continue,
363 Err(err) => {
364 break;
365 }
366 }
367 }
368 });
369 }
370 Err(_err) => {
371 break;
372 }
373 }
374 }
375 }};
376
377 (@async_loop_body $protocol:path, $listener:ident, $handler:ident, $error_tx:ident, $ok_tx:ident, $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?) => {{
378 loop {
379 match $listener.accept().await {
380 Ok((mut __transport, _addr)) => {
381 $(
382 $(
383 __transport = $crate::server!(@apply_one_policy __transport, $policy_name, $policy_expr);
384 )*
385 )*
386 let __handler_clone = ::std::sync::Arc::clone(&$handler);
387 let mut __error_channel = $error_tx.clone();
388 let mut __ok_channel = $ok_tx.clone();
389 use $crate::transport::MessageCollector;
390 $crate::macros::server::server_runtime::rt::spawn(async move {
391 let mut __transport = __transport;
392 loop {
393 let (frame, status) = match __transport.collect_message().await {
395 Ok(result) => result,
396 Err(err) => {
397 if let Some(tx) = __error_channel.as_mut() {
398 let _ = tx.send(err).await;
399 }
400 break;
401 }
402 };
403
404 let frame_owned = std::sync::Arc::try_unwrap(frame)
407 .unwrap_or_else(|arc| (*arc).clone());
408 let response = if status == $crate::policy::TransitStatus::Accepted {
409 match (__handler_clone)(frame_owned).await {
410 Ok(opt) => opt,
411 Err(_err) => {
412 None
413 }
414 }
415 } else {
416 None
417 };
418
419 match __transport.send_response(status, response).await {
421 Ok(()) => {
422 if let Some(tx) = __ok_channel.as_mut() {
423 let _ = tx.send(()).await;
424 }
425 }
426 Err(err) => {
427 if let Some(tx) = __error_channel.as_mut() {
428 let _ = tx.send(err).await;
429 }
430 break;
431 }
432 }
433 }
434 });
435 }
436 Err(e) => {
437 if let Some(tx) = $error_tx.as_mut() {
438 let _ = tx.send(e.into()).await;
439 }
440
441 break;
442 }
443 }
444 }
445 }};
446
447 (@sync_loop $protocol:path, $listener:expr, $handler:expr, $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?) => {{
448 let mut __listener = $listener;
449 let __handler = $crate::macros::server::into_shared_handler($handler);
450
451 $crate::server!(@sync_loop_body $protocol, __listener, __handler, $($policy_name: [ $( $policy_expr ),* ]),*);
452 }};
453
454 (@async_loop_assertions $protocol:path, $listener:expr, $assertions:expr, ($param1:ident, $param2:ident, $handler_body:expr), $error_tx:expr, $ok_tx:expr, $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?) => {{
455 #[allow(unused_imports)]
456 use $crate::trace::TraceCollector;
457
458 let __assertions = ::std::sync::Arc::new($assertions);
459 let __handler_with_trace = {
460 let __assertions = ::std::sync::Arc::clone(&__assertions);
461 move |$param1: $crate::Frame| {
462 let $param2: TraceCollector = __assertions.as_ref().share();
463 $handler_body
464 }
465 };
466
467 $crate::server!(@async_loop $protocol, $listener, __handler_with_trace, $error_tx, $ok_tx, $($policy_name: [ $( $policy_expr ),* ]),*);
468 }};
469
470 (@async_loop $protocol:path, $listener:expr, $handler:expr, $error_tx:expr, $ok_tx:expr, $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)?) => {{
471 let mut __listener = $listener;
472 let __handler = $crate::macros::server::into_shared_handler($handler);
473 let mut __error_tx = $error_tx;
474 let mut __ok_tx = $ok_tx;
475
476 $crate::server!(@async_loop_body $protocol, __listener, __handler, __error_tx, __ok_tx, $($policy_name: [ $( $policy_expr ),* ]),*);
477 }};
478
479 ($protocol:path: $listener:expr, handle: $handler:expr) => {{
480 #[cfg(feature = "std")]
481 {
482 let __listener = $listener;
483 $crate::server!(@sync_loop $protocol, __listener, $handler,)
484 }
485 }};
486
487 ($protocol:path: bind $addr:expr, handle: $handler:expr) => {{
488 #[cfg(feature = "std")]
489 {
490 let (listener, _) = <$protocol as $crate::transport::Protocol>::bind($addr)?;
491 let __server = <$protocol>::from(listener);
492 $crate::server!(@sync_loop $protocol, __server, $handler,)
493 }
494 }};
495
496 ($protocol:path: $listener:expr, policies: { $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)? }, handle: $handler:expr) => {{
497 #[cfg(feature = "std")]
498 {
499 let __listener = $listener;
500 $crate::server!(@sync_loop $protocol, __listener, $handler, $($policy_name: [ $( $policy_expr ),* ]),*);
501 }
502 }};
503
504 ($protocol:path: bind $addr:expr, policies: { $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)? }, handle: $handler:expr) => {{
505 #[cfg(feature = "std")]
506 {
507 let (listener, _) = <$protocol as $crate::transport::Protocol>::bind($addr)?;
508 let __server = <$protocol>::from(listener);
509 $crate::server!(@sync_loop $protocol, __server, $handler, $($policy_name: [ $( $policy_expr ),* ]),*);
510 }
511 }};
512
513 (protocol $protocol:path: $listener:expr, handle: $handler:expr) => {{
514 $crate::__tightbeam_server_protocol_handle!($protocol, $listener, $handler)
515 }};
516
517 (protocol $protocol:path: $listener:expr, assertions: $assertions:expr, handle: move |$param1:ident, $param2:ident| $handler_body:expr) => {{
518 $crate::__tightbeam_server_protocol_handle!($protocol, $listener, assertions: $assertions, ($param1, $param2, $handler_body))
519 }};
520
521 (protocol $protocol:path: $listener:expr, assertions: $assertions:expr, handle: |$param1:ident, $param2:ident| $handler_body:expr) => {{
522 $crate::__tightbeam_server_protocol_handle!($protocol, $listener, assertions: $assertions, ($param1, $param2, $handler_body))
523 }};
524
525 (protocol $protocol:path: bind $addr:expr, handle: $handler:expr) => {{
526 $crate::__tightbeam_server_protocol_bind_handle!($protocol, $addr, $handler)
527 }};
528
529 (protocol $protocol:path: $listener:expr, policies: { $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)? }, handle: $handler:expr) => {{
530 $crate::__tightbeam_server_protocol_policies_handle!($protocol, $listener, [ $($policy_name: [ $( $policy_expr ),* ]),* ], $handler)
531 }};
532
533 (protocol $protocol:path: $listener:expr, policies: { $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)? }, assertions: $assertions:expr, handle: move |$param1:ident, $param2:ident| $handler_body:expr) => {{
534 $crate::__tightbeam_server_protocol_policies_assertions_handle!(
535 $protocol,
536 $listener,
537 [ $($policy_name: [ $( $policy_expr ),* ]),* ],
538 $assertions,
539 ($param1, $param2, $handler_body)
540 )
541 }};
542
543 (protocol $protocol:path: $listener:expr, policies: { $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)? }, assertions: $assertions:expr, handle: |$param1:ident, $param2:ident| $handler_body:expr) => {{
544 $crate::__tightbeam_server_protocol_policies_assertions_handle!(
545 $protocol,
546 $listener,
547 [ $($policy_name: [ $( $policy_expr ),* ]),* ],
548 $assertions,
549 ($param1, $param2, $handler_body)
550 )
551 }};
552
553 (protocol $protocol:path: $listener:expr, assertions: $assertions:expr, policies: { $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)? }, handle: move |$param1:ident, $param2:ident| $handler_body:expr) => {{
554 $crate::__tightbeam_server_protocol_policies_assertions_handle!(
555 $protocol,
556 $listener,
557 [ $($policy_name: [ $( $policy_expr ),* ]),* ],
558 $assertions,
559 ($param1, $param2, $handler_body)
560 )
561 }};
562
563 (protocol $protocol:path: $listener:expr, assertions: $assertions:expr, policies: { $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)? }, handle: |$param1:ident, $param2:ident| $handler_body:expr) => {{
564 $crate::__tightbeam_server_protocol_policies_assertions_handle!(
565 $protocol,
566 $listener,
567 [ $($policy_name: [ $( $policy_expr ),* ]),* ],
568 $assertions,
569 ($param1, $param2, $handler_body)
570 )
571 }};
572
573 (protocol $protocol:path: $listener:expr, channels: { error: $error_tx:expr, ok: $ok_tx:expr }, handle: $handler:expr) => {{
574 $crate::__tightbeam_server_protocol_channels_handle!($protocol, $listener, $error_tx, $ok_tx, $handler)
575 }};
576
577 (protocol $protocol:path: $listener:expr, channels: { error: $error_tx:expr, ok: $ok_tx:expr }, policies: { $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)? }, handle: $handler:expr) => {{
578 $crate::__tightbeam_server_protocol_channels_policies_handle!($protocol, $listener, $error_tx, $ok_tx, [ $($policy_name: [ $( $policy_expr ),* ]),* ], $handler)
579 }};
580
581 (protocol $protocol:path: bind $addr:expr, policies: { $($policy_name:ident: [ $( $policy_expr:expr ),* $(,)? ]),* $(,)? }, handle: $handler:expr) => {{
582 $crate::__tightbeam_server_protocol_bind_policies_handle!($protocol, $addr, [ $($policy_name: [ $( $policy_expr ),* ]),* ], $handler)
583 }};
584
585 (async $($rest:tt)*) => {
586 $crate::server!(protocol $($rest)*)
587 };
588}