data_router/
multi_router.rs1#![allow(unused)]
2
3macro_rules! list_helper {
4 ($f:ident, $last:ident, $value:expr) => {
5 write!($f, "{}: {}",stringify!($last), $value)?;
6 };
7 ($f:ident, $first:ident, $value:expr, $($rest:ident, $rest_value:expr),*) => {
8 write!($f, "{}: {}, ",stringify!($first), $value)?;
9 $crate::event_horizon::multi_router::list_helper!($f, $($rest, $rest_value),*)
10 }
11}
12
13pub trait MultiRoute<I: ?Sized> {
14 fn take_intercept(&mut self) -> Option<Box<I>>;
15 fn delete_top_intercept(&mut self) -> Option<Box<I>>;
16 fn intercept(&mut self, intercept: Box<I>);
17}
18
19#[allow(unused)]
20macro_rules! multi_router_intercept_trait {
21 ($vis:vis $I:ident for $($E:ty)|*) => {
22 $vis trait $I: $($crate::event_horizon::receive::Receive<$E, Output = $E>+)* {
23 fn take_intercept(&mut self) -> Option<Box<dyn $I>>;
24 fn intercept(&mut self, intercept: Box<dyn $I>);
25 }
26 };
27}
28
29#[allow(unused)]
30macro_rules! impl_multi_router_intercept_trait {
31 ($Name:ident as $I:ident for $($E:ty)|*) => {
32 impl<R: $($crate::event_horizon::receive::Receive<$E, Output = $E>+)*> $I for $Name<R> {
33 fn take_intercept(&mut self) -> Option<Box<dyn $I>> {
34 (self as &mut dyn crate::event_horizon::multi_router::MultiRoute<dyn $I>).take_intercept()
35 }
36 fn intercept(&mut self, intercept: Box<dyn $I>) {
37 (self as &mut dyn crate::event_horizon::multi_router::MultiRoute<dyn $I>).intercept(intercept)
38 }
39 }
40 };
41}
42
43#[allow(unused)]
44macro_rules! multi_router {
45 (#[derive($($attr:ident),*)] $vis:vis $Name:ident { $($intercept:ident as $I:ident where $($E:ty => $Output:ty)|*),* } else { $($P:ty => $POutput:ty),* }) => {
46 #[derive($($attr),*)]
47 $vis struct $Name<R> {
48 $($intercept: Option<Box<dyn $I>>,)*
49 receiver: R,
50 }
51
52 impl<R> $Name<R> {
53 pub fn new(receiver: R) -> Self {
54 Self { receiver, $($intercept: None),* }
55 }
56
57 #[allow(unused)]
58 pub fn get_receiver(&self) -> &R {
59 &self.receiver
60 }
61
62 #[allow(unused)]
63 pub fn get_receiver_mut(&mut self) -> &mut R {
64 &mut self.receiver
65 }
66
67 $(pub fn $intercept (&self) -> Option<&dyn $I> {
68 self.$intercept.as_ref().map(Box::as_ref)
69 })*
70 }
71
72 $($(impl<R: $crate::event_horizon::receive::Receive<$E, Output = $Output>> $crate::event_horizon::receive::Receive<$E> for $Name<R> {
73 type Output = $Output;
74
75 fn send(&mut self, event: $E) -> $crate::event_horizon::receive::ReceiverResult<$E, Self::Output> {
76 let event = if let Some(ref mut intercept) = self.$intercept {
77 match intercept.send(event) {
78 $crate::event_horizon::receive::ReceiverResult::Continue(event) => event,
79 $crate::event_horizon::receive::ReceiverResult::Stop => return $crate::event_horizon::receive::ReceiverResult::Stop,
80 $crate::event_horizon::receive::ReceiverResult::Delete(event) => {
81 (self as &mut dyn $crate::event_horizon::multi_router::MultiRoute<dyn $I>).delete_top_intercept().unwrap();
82 event
83 }
84 }
85 } else {
86 event
87 };
88
89 self.receiver.send(event)
90 }
91 })*)*
92
93 $(impl<R: $crate::event_horizon::receive::Receive<$P, Output = $POutput>> $crate::event_horizon::receive::Receive<$P> for $Name<R> {
94 type Output = $POutput;
95
96 fn send(&mut self, event: $P) -> $crate::event_horizon::receive::ReceiverResult<$P, Self::Output> {
97 self.receiver.send(event)
98 }
99 })*
100
101 $(impl<R> $crate::event_horizon::multi_router::MultiRoute<dyn $I> for $Name<R> {
102 fn take_intercept(&mut self) -> Option<Box<dyn $I>> {
103 self.$intercept.take()
104 }
105
106 fn delete_top_intercept(&mut self) -> Option<Box<dyn $I>> {
107 let mut old_intercept = self.take_intercept();
108 if let Some(ref mut intercept) = old_intercept {
109 self.$intercept = (intercept as &mut Box<dyn $I>).take_intercept();
110 }
111 old_intercept
112 }
113
114 fn intercept(&mut self, intercept: Box<dyn $I>) {
115 match self.$intercept {
116 Some(ref mut child) => child.intercept(intercept),
117 None => self.$intercept = Some(intercept),
118 }
119 }
120 })*
121
122 impl<R> Default for $Name<R> where R: Default {
123 fn default() -> Self {
124 Self::new(R::default())
125 }
126 }
127
128 impl<R> std::fmt::Debug for $Name<R> where R: std::fmt::Debug {
129 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130 write!(f, "{{[")?;
131 $crate::event_horizon::multi_router::list_helper!(f, $($intercept, match self.$intercept.as_ref() {
132 Some(_) => "intercepted",
133 None => "n/a",
134 }),*);
135 write!(f, "], ")?;
136 write!(f, "{:?}}}", self.receiver)
137 }
138 }
139
140 impl<R> std::fmt::Display for $Name<R> where R: std::fmt::Display {
141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142 self.receiver.fmt(f)
143 }
144 }
145 };
146 (#[derive($($attr:ident),*)] $vis:vis $Name:ident { $($intercept:ident as $I:ident where $($E:ty => $Output:ty)|*),* }) => {
147 $crate::event_horizon::multi_router::multi_router!(#[derive($($attr),*)] $vis $Name { $($intercept as $I where $($E => $Output)|*),* } else {});
148 };
149 (#[derive($($attr:ident),*)] $vis:vis $Name:ident { $($intercept:ident as $I:ident where $($E:ty)|*),* } else { $($P:ty),* }) => {
150 $crate::event_horizon::multi_router::multi_router!(#[derive($($attr),*)] $vis $Name { $($intercept as $I where $($E => $E)|*),* } else { $($P => $P),* });
151 };
152 (#[derive($($attr:ident),*)] $vis:vis $Name:ident { $($intercept:ident as $I:ident where $($E:ty)|*),* }) => {
153 $crate::event_horizon::multi_router::multi_router!(#[derive($($attr),*)] $vis $Name { $($intercept as $I where $($E)|*),* } else {});
154 };
155 ($vis:vis $Name:ident { $($intercept:ident as $I:ident where $($E:ty => $Output:ty)|*),* } else { $($P:ty => $POutput:ty),* }) => {
156 $crate::event_horizon::multi_router::multi_router!(#[derive()] $vis $Name { $($intercept as $I where $($E => $Output)|*),* } else { $($P => $POutput),* });
157 };
158 ($vis:vis $Name:ident { $($intercept:ident as $I:ident where $($E:ty => $Output:ty)|*),* }) => {
159 $crate::event_horizon::multi_router::multi_router!(#[derive()] $vis $Name { $($intercept as $I where $($E => $Output)|*),* } else {});
160 };
161 ($vis:vis $Name:ident { $($intercept:ident as $I:ident where $($E:ty)|*),* } else { $($P:ty),* }) => {
162 $crate::event_horizon::multi_router::multi_router!(#[derive()] $vis $Name { $($intercept as $I where $($E => $E)|*),* } else { $($P => $P),* });
163 };
164 ($vis:vis $Name:ident { $($intercept:ident as $I:ident where $($E:ty)|*),* }) => {
165 $crate::event_horizon::multi_router::multi_router!(#[derive()] $vis $Name { $($intercept as $I where $($E)|*),* } else {});
166 };
167}
168
169pub(crate) use impl_multi_router_intercept_trait;
170pub(crate) use list_helper;
171pub(crate) use multi_router;
172pub(crate) use multi_router_intercept_trait;