reach_websocket/server/
macros.rs

1// SPDX-FileCopyrightText: 2025 eaon <eaon@posteo.net>
2// SPDX-License-Identifier: EUPL-1.2
3
4#[macro_export]
5#[doc(hidden)]
6macro_rules! _request_delegator {
7    (
8        $delegator:tt,
9        $communication:ty,
10        $global_context:ty,
11        $session_context:ty,
12        $request_wrapper:tt,
13        ($($request:tt),*$(,)?)$(,)?
14    ) => {
15        pub struct $delegator;
16
17        impl reach_websocket::RequestDelegator<$communication> for $delegator {
18            type GlobalContext = $global_context;
19            type SessionContext = $session_context;
20
21            async fn delegate(
22                item: reach_websocket::RawWebSocketItem<
23                    <$communication as reach_core::communication::CommunicableTypes>::Req,
24                    <$communication as reach_core::communication::CommunicableTypes>::Resp,
25                >,
26                global_context: std::sync::Arc<Self::GlobalContext>,
27                session_context: std::sync::Arc<tokio::sync::RwLock<Self::SessionContext>>,
28            ) -> Result<(), reach_websocket::RespondToItemError> {
29                match item.item.r#type {
30                    $(
31                        <
32                            $communication as reach_core::communication::CommunicableTypes
33                        >::Req::$request => {
34                            log::debug!("Delegating {:?} request to handler", item.item.r#type);
35                            reach_websocket::respond_to_item::<
36                                $communication,
37                                $request_wrapper<$request>,
38                            >(item, global_context, session_context).await
39                        }
40                    )*
41                    _ => {
42                        log::warn!("No request handler for {:?} found", item.item.r#type);
43                        item.unsupported();
44
45                        Err(reach_websocket::RespondToItemError::Unsupported)
46                    }
47                }
48            }
49        }
50    };
51}
52
53#[doc(inline)]
54pub use _request_delegator as request_delegator;
55
56#[macro_export]
57#[doc(hidden)]
58macro_rules! _request_wrapper {
59    ($request_wrapper:tt, $request_enum:ty) => {
60        #[derive(Debug)]
61        pub struct $request_wrapper<T> {
62            pub inner: T,
63        }
64
65        impl<T> std::ops::Deref for $request_wrapper<T> {
66            type Target = T;
67
68            fn deref(&self) -> &Self::Target {
69                &self.inner
70            }
71        }
72
73        impl<T> reach_core::communication::MatchResponse<$request_enum> for $request_wrapper<T>
74        where
75            T: reach_core::communication::MatchResponse<$request_enum>,
76        {
77            type Resp = T::Resp;
78        }
79
80        impl<T> reach_core::communication::Communicable<$request_enum> for $request_wrapper<T>
81        where
82            T: reach_core::communication::Communicable<$request_enum>,
83        {
84            fn to_communication(&self) -> reach_core::communication::Communication<$request_enum> {
85                self.inner.to_communication()
86            }
87
88            fn try_from_communication(
89                communication: &reach_core::communication::Communication<$request_enum>,
90            ) -> Result<Self, reach_core::error::DecodeError> {
91                Ok(Self {
92                    inner: T::try_from_communication(communication)?,
93                })
94            }
95        }
96    };
97}
98
99#[doc(inline)]
100pub use _request_wrapper as request_wrapper;