1#[macro_export]
134macro_rules! rpc_service {
135 (
136 Request = $request:ident;
137 Response = $response:ident;
138 Service = $service:ident;
139 CreateDispatch = $create_dispatch:tt;
140
141 $($m_pattern:ident $m_name:ident = $m_input:ident, $m_update:tt -> $m_output:ident);+$(;)?
142 ) => {
143
144 $crate::__request_enum! {
145 $service,
146 $request {
147 $($m_input,)*
148 $($m_update,)*
149 }
150 }
151
152 #[doc=concat!("Response messages for ", stringify!($service))]
153 #[allow(clippy::enum_variant_names)]
154 #[derive(::std::fmt::Debug, ::derive_more::From, ::derive_more::TryInto, ::serde::Serialize, ::serde::Deserialize)]
155 pub enum $response {
156 $($m_output($m_output),)*
157 }
158
159 $(
160 $crate::__rpc_message!($service, $m_pattern, $m_input, $m_update, $m_output);
161 )*
162
163 #[doc=concat!("RPC service ", stringify!($service))]
164 #[derive(::std::clone::Clone, ::std::fmt::Debug)]
165 pub struct $service;
166
167 impl $crate::Service for $service {
168 type Req = $request;
169 type Res = $response;
170 }
171
172 $crate::__derive_create_dispatch!(
173 $service,
174 $request,
175 $create_dispatch,
176 [ $($m_pattern $m_name = $m_input, $m_update -> $m_output);+ ]
177 );
178 };
179}
180
181#[doc(hidden)]
182#[macro_export]
183macro_rules! __derive_create_dispatch {
184 (
185 $service:ident,
186 $request:ident,
187 _,
188 [ $($tt:tt)* ]
189 ) => {};
190 (
191 $service:ident,
192 $request:ident,
193 $create_dispatch:ident,
194 [ $($m_pattern:ident $m_name:ident = $m_input:ident, $m_update:tt -> $m_output:ident);+ ]
195 ) => {
196 #[doc = concat!("Create an RPC request dispatch function for ", stringify!($service), "\n\nSee the docs for [quic_rpc::rpc_service] for usage docs.")]
197 #[macro_export]
198 macro_rules! $create_dispatch {
199 ($target:ident, $handler:ident) => {
200 pub async fn $handler<C: $crate::Listener<$service>>(
201 mut chan: $crate::server::RpcChannel<$service, C>,
202 msg: <$service as $crate::Service>::Req,
203 target: $target,
204 ) -> Result<(), $crate::server::RpcServerError<C>> {
205 let res = match msg {
206 $(
207 $request::$m_input(msg) => { $crate::__rpc_invoke!($m_pattern, $m_name, $target, msg, chan, target) },
208 )*
209 _ => Err($crate::server::RpcServerError::<C>::UnexpectedStartMessage),
210 };
211 res?;
212 Ok(())
213 }
214 }
215 }
216 };
217}
218
219#[doc(hidden)]
220#[macro_export]
221macro_rules! __request_enum {
222 ($service:ident, $enum_name:ident { $variant_name:ident $($tt:tt)* }) => {
224 $crate::__request_enum!(@ {[$service $enum_name] [$variant_name]} $($tt)*);
225 };
226
227 (@ {[$service:ident $enum_name:ident] [$($agg:ident)*]} $(,)? $(_$(,)?)* $variant_name:ident $($tt:tt)*) => {
230 $crate::__request_enum!(@ {[$service $enum_name] [$($agg)* $variant_name]} $($tt)*);
231 };
232
233 (@ {[$service:ident $enum_name:ident] [$($agg:ident)*]} $(,)? $variant_name:ident $($tt:tt)*) => {
235 $crate::__request_enum!(@ {[$service $enum_name] [$($agg)* $variant_name]} $($tt)*);
236 };
237
238 (@ {[$service:ident $enum_name:ident] [$($n:ident)*]} $(,)? $(_$(,)?)*) => {
240 #[doc=concat!("Request messages for ", stringify!($service))]
241 #[derive(::std::fmt::Debug, ::derive_more::From, ::derive_more::TryInto, ::serde::Serialize, ::serde::Deserialize)]
242 pub enum $enum_name {
243 $($n($n),)*
244 }
245 };
246}
247
248#[macro_export]
262macro_rules! declare_rpc {
263 ($service:ty, $m_input:ty, $m_output:ty) => {
264 impl $crate::message::RpcMsg<$service> for $m_input {
265 type Response = $m_output;
266 }
267 };
268}
269
270#[macro_export]
287macro_rules! declare_server_streaming {
288 ($service:ident, $m_input:ident, $m_output:ident) => {
289 impl $crate::message::Msg<$service> for $m_input {
290 type Pattern = $crate::message::ServerStreaming;
291 }
292 impl $crate::message::ServerStreamingMsg<$service> for $m_input {
293 type Response = $m_output;
294 }
295 };
296}
297
298#[macro_export]
317macro_rules! declare_client_streaming {
318 ($service:ident, $m_input:ident, $m_update:ident, $m_output:ident) => {
319 impl $crate::message::Msg<$service> for $m_input {
320 type Pattern = $crate::message::ClientStreaming;
321 }
322 impl $crate::message::ClientStreamingMsg<$service> for $m_input {
323 type Update = $m_update;
324 type Response = $m_output;
325 }
326 };
327}
328
329#[macro_export]
348macro_rules! declare_bidi_streaming {
349 ($service:ident, $m_input:ident, $m_update:ident, $m_output:ident) => {
350 impl $crate::message::Msg<$service> for $m_input {
351 type Pattern = $crate::message::BidiStreaming;
352 }
353 impl $crate::message::BidiStreamingMsg<$service> for $m_input {
354 type Update = $m_update;
355 type Response = $m_output;
356 }
357 };
358}
359
360#[doc(hidden)]
361#[macro_export]
362macro_rules! __rpc_message {
363 ($service:ident, Rpc, $m_input:ident, _, $m_output:ident) => {
364 impl $crate::message::RpcMsg<$service> for $m_input {
365 type Response = $m_output;
366 }
367 };
368 ($service:ident, ServerStreaming, $m_input:ident, _, $m_output:ident) => {
369 impl $crate::message::Msg<$service> for $m_input {
370 type Pattern = $crate::message::ServerStreaming;
371 }
372 impl $crate::message::ServerStreamingMsg<$service> for $m_input {
373 type Response = $m_output;
374 }
375 };
376 ($service:ident, ClientStreaming, $m_input:ident, $m_update:ident, $m_output:ident) => {
377 impl $crate::message::Msg<$service> for $m_input {
378 type Pattern = $crate::message::ClientStreaming;
379 }
380 impl $crate::message::ClientStreamingMsg<$service> for $m_input {
381 type Response = $m_output;
382 type Update = $m_update;
383 }
384 };
385 ($service:ident, BidiStreaming, $m_input:ident, $m_update:ident, $m_output:ident) => {
386 impl $crate::message::Msg<$service> for $m_input {
387 type Pattern = $crate::message::BidiStreaming;
388 }
389 impl $crate::message::BidiStreamingMsg<$service> for $m_input {
390 type Response = $m_output;
391 type Update = $m_update;
392 }
393 };
394}
395
396#[doc(hidden)]
397#[macro_export]
398macro_rules! __rpc_invoke {
399 (Rpc, $m_name:ident, $target_ty:ident, $msg:ident, $chan:ident, $target:ident) => {
400 $chan.rpc($msg, $target, $target_ty::$m_name).await
401 };
402 (ClientStreaming, $m_name:ident, $target_ty:ident, $msg:ident, $chan:ident, $target:ident) => {
403 $chan
404 .client_streaming($msg, $target, $target_ty::$m_name)
405 .await
406 };
407 (ServerStreaming, $m_name:ident, $target_ty:ident, $msg:ident, $chan:ident, $target:ident) => {
408 $chan
409 .server_streaming($msg, $target, $target_ty::$m_name)
410 .await
411 };
412 (BidiStreaming, $m_name:ident, $target_ty:ident, $msg:ident, $chan:ident, $target:ident) => {
413 $chan
414 .bidi_streaming($msg, $target, $target_ty::$m_name)
415 .await
416 };
417}
418
419#[doc(hidden)]
420#[macro_export]
421macro_rules! __derive_create_client{
422 (
423 $service:ident,
424 _,
425 [ $($tt:tt)* ]
426 ) => {};
427 (
428 $service:ident,
429 $create_client:tt,
430 [ $($m_pattern:ident $m_name:ident = $m_input:ident, $m_update:tt -> $m_output:ident);+ ]
431 ) => {
432 #[doc = concat!("Create an RPC client for ", stringify!($service), "\n\nSee the docs for [quic_rpc::rpc_service] for usage docs.")]
433 #[macro_export]
434 macro_rules! $create_client {
435 ($struct:ident) => {
436 #[derive(::std::clone::Clone, ::std::fmt::Debug)]
437 pub struct $struct<C: $crate::Listener<$service>>(pub $crate::client::RpcClient<$service, C>);
438
439 impl<C: $crate::Listener<$service>> $struct<C> {
440 $(
441 $crate::__rpc_method!($m_pattern, $service, $m_name, $m_input, $m_output, $m_update);
442 )*
443 }
444 };
445 }
446 };
447}
448
449#[doc(hidden)]
450#[macro_export]
451macro_rules! __rpc_method {
452 (Rpc, $service:ident, $m_name:ident, $m_input:ident, $m_output:ident, _) => {
453 pub async fn $m_name(
454 &mut self,
455 input: $m_input,
456 ) -> ::std::result::Result<$m_output, $crate::client::RpcClientError<C>> {
457 self.0.rpc(input).await
458 }
459 };
460 (ClientStreaming, $service:ident, $m_name:ident, $m_input:ident, $m_output:ident, $m_update:ident) => {
461 pub async fn $m_name(
462 &mut self,
463 input: $m_input,
464 ) -> ::std::result::Result<
465 (
466 $crate::client::UpdateSink<$service, C, $m_input>,
467 ::futures::future::BoxFuture<
468 'static,
469 ::std::result::Result<$m_output, $crate::client::ClientStreamingItemError<C>>,
470 >,
471 ),
472 $crate::client::ClientStreamingError<C>,
473 > {
474 self.0.client_streaming(input).await
475 }
476 };
477 (ServerStreaming, $service:ident, $m_name:ident, $m_input:ident, $m_output:ident, _) => {
478 pub async fn $m_name(
479 &mut self,
480 input: $m_input,
481 ) -> ::std::result::Result<
482 ::futures::stream::BoxStream<
483 'static,
484 ::std::result::Result<$m_output, $crate::client::StreamingResponseItemError<C>>,
485 >,
486 $crate::client::StreamingResponseError<C>,
487 > {
488 self.0.server_streaming(input).await
489 }
490 };
491 (BidiStreaming, $service:ident, $m_name:ident, $m_input:ident, $m_output:ident, $m_update:ident) => {
492 pub async fn $m_name(
493 &mut self,
494 input: $m_input,
495 ) -> ::std::result::Result<
496 (
497 $crate::client::UpdateSink<$service, C, $m_input>,
498 ::futures::stream::BoxStream<
499 'static,
500 ::std::result::Result<$m_output, $crate::client::BidiItemError<C>>,
501 >,
502 ),
503 $crate::client::BidiError<C>,
504 > {
505 self.0.bidi(input).await
506 }
507 };
508}