angzarr_client/router/dispatch.rs
1//! Dispatch helpers for routing events/commands by type URL.
2
3/// Helper macro for dispatching events by type URL suffix.
4///
5/// Simplifies the common pattern of matching event type URLs and delegating
6/// to handler methods.
7///
8/// # Example
9///
10/// ```rust,ignore
11/// use angzarr_client::dispatch_event;
12///
13/// impl SagaDomainHandler for OrderSagaHandler {
14/// fn execute(
15/// &self,
16/// source: &EventBook,
17/// event: &Any,
18/// destinations: &[EventBook],
19/// ) -> CommandResult<Vec<CommandBook>> {
20/// dispatch_event!(event, source, destinations, {
21/// "OrderCompleted" => self.handle_completed,
22/// "OrderCancelled" => self.handle_cancelled,
23/// })
24/// }
25/// }
26/// ```
27///
28/// # Variants
29///
30/// ## For saga execute (source + destinations)
31/// ```rust,ignore
32/// dispatch_event!(event, source, destinations, {
33/// "Suffix" => handler_method,
34/// })
35/// ```
36///
37/// ## For saga prepare (source only, returns Vec<Cover>)
38/// ```rust,ignore
39/// dispatch_event!(event, source, {
40/// "Suffix" => prepare_method,
41/// })
42/// ```
43#[macro_export]
44macro_rules! dispatch_event {
45 // Saga execute variant: (event, source, destinations, handlers)
46 ($event:expr, $source:expr, $destinations:expr, { $($suffix:literal => $handler:expr),* $(,)? }) => {{
47 let type_url = &$event.type_url;
48 $(
49 if type_url.ends_with($suffix) {
50 return $handler($source, $event, $destinations);
51 }
52 )*
53 Ok(vec![])
54 }};
55
56 // Saga prepare variant: (event, source, handlers) -> Vec<Cover>
57 ($event:expr, $source:expr, { $($suffix:literal => $handler:expr),* $(,)? }) => {{
58 let type_url = &$event.type_url;
59 $(
60 if type_url.ends_with($suffix) {
61 return $handler($source, $event);
62 }
63 )*
64 vec![]
65 }};
66}
67
68/// Helper macro for dispatching commands by type URL suffix.
69///
70/// Similar to `dispatch_event!` but for command handler handlers.
71///
72/// # Example
73///
74/// ```rust,ignore
75/// use angzarr_client::dispatch_command;
76///
77/// impl CommandHandlerDomainHandler for PlayerHandler {
78/// fn handle(
79/// &self,
80/// cmd: &CommandBook,
81/// payload: &Any,
82/// state: &PlayerState,
83/// seq: u32,
84/// ) -> CommandResult<EventBook> {
85/// dispatch_command!(payload, cmd, state, seq, {
86/// "RegisterPlayer" => self.handle_register,
87/// "DepositFunds" => self.handle_deposit,
88/// })
89/// }
90/// }
91/// ```
92#[macro_export]
93macro_rules! dispatch_command {
94 ($payload:expr, $cmd:expr, $state:expr, $seq:expr, { $($suffix:literal => $handler:expr),* $(,)? }) => {{
95 let type_url = &$payload.type_url;
96 $(
97 if type_url.ends_with($suffix) {
98 return $handler($cmd, $payload, $state, $seq);
99 }
100 )*
101 Err($crate::CommandRejectedError::new(format!("Unknown command type: {}", type_url)))
102 }};
103}
104
105// Macros are exported at crate level via #[macro_export]
106// Re-exported from router module for documentation purposes