1pub use paste::paste;
2
3#[macro_export]
4macro_rules! Sum {
5 ( $(,)? ) => {
6 $crate::choice::nary::Bottom
7 };
8 ( $e:ty ) => {
9 $crate::prelude::Sum <
10 $e,
11 $crate::prelude::Bottom
12 >
13 };
14 ( $e:ty, $($tail:tt)* ) => {
15 $crate::prelude::Sum < $e, $crate::prelude::Sum!( $( $tail )* ) >
16 };
17}
18
19#[macro_export]
20macro_rules! HList {
21 ( $(,)? ) => {
22 ()
23 };
24 ( $e:ty ) => {
25 ( $e, () )
26 };
27 ( $e:ty, $($tail:tt)* ) => {
28 ( $e, $crate::prelude::HList!( $($tail)* ) )
29 };
30}
31
32#[macro_export]
33macro_rules! match_choice_value {
34 ( $choice:expr; $( $label:path => $e:expr $(,)? )+ ) => {
35 match $crate::prelude::extract_choice( $choice ) {
36 $(
37 $label ( cont ) => {
38 $crate::prelude::run_cont ( cont,
39 $crate::prelude::step ( async move {
40 $e
41 })
42 )
43 }
44 )*
45 }
46 }
47}
48
49#[macro_export]
50macro_rules! match_choice {
51 ( $( $label:path => $e:expr $(,)? )+ ) => {
52 move | ferrite_choice_internal__ | {
53 $crate::match_choice_value! { ferrite_choice_internal__;
54 $( $label => $e ),*
55 }
56 }
57 };
58}
59
60#[macro_export]
61macro_rules! offer_choice {
62 ( $( $label:path => $e:expr $(,)? )+ ) => {
63 $crate::prelude::offer_choice (
64 $crate::match_choice! {
65 $( $label => $e ),*
66 }
67 )
68 }
69}
70
71#[macro_export]
72macro_rules! case {
73 ( $chan:expr ; $( $label:path => $e:expr $(,)? )+ ) => {
74 $crate::prelude::case ( $chan,
75 $crate::match_choice! {
76 $( $label => $e ),*
77 }
78 )
79 }
80}
81
82#[macro_export]
83macro_rules! define_choice_protocol {
84 ( $name:ident ;
85 $( $protocols:ty ),+ $(,)?
86 ) => {
87 pub enum $name {}
88
89 impl $crate::prelude::ToRow for $name {
90 type Row = $crate::prelude::HList![ $( $protocols ),* ];
91 }
92 };
93
94 ( $name:ident
95 < $( $types:ident ),+ $(,)? > ;
96 $( $protocols:ty ),+ $(,)?
97 ) => {
98 pub struct $name <$( $types ),*>
99 {
100 phantom: std::marker::PhantomData<($( $types ),*)>
101 }
102
103 impl < $( $types ),* >
104 $crate::prelude::ToRow for $name < $( $types ),* >
105 {
106 type Row = $crate::prelude::HList![ $( $protocols ),* ];
107 }
108 };
109}
110
111#[macro_export]
112macro_rules! define_choice_labels {
113 ( $( $labels:ident ),+ $(,)? ) => {
114 $crate::define_choice_labels![ $crate::prelude::Z; $( $labels ),* ];
115 };
116 ( $acc:ty; $label:ident ) => {
117 $crate::macros::paste! {
118 #[allow(non_upper_case_globals)]
119 pub const [< $label Label >]
120 : $crate::prelude::ChoiceSelector < $acc > =
121 < $crate::prelude::ChoiceSelector < $acc > >::new();
122 }
123 };
124 ( $acc:ty; $label:ident, $( $labels:ident ),+ ) => {
125 $crate::macros::paste! {
126 #[allow(non_upper_case_globals)]
127 pub const [< $label Label >]
128 : $crate::prelude::ChoiceSelector < $acc > =
129 < $crate::prelude::ChoiceSelector < $acc > >::new();
130
131 $crate::define_choice_labels![
132 $crate::prelude::S < $acc >;
133 $( $labels ),*
134 ];
135 }
136 };
137}
138
139#[macro_export]
140macro_rules! define_choice_enum {
141 ( $name:ident; $( $labels:ident ),+ $(,)? ) => {
142 $crate::macros::paste! {
143 pub enum [< $name Choice >]
144 < $( [< $labels T >] ),* >
145 {
146 $( $labels ( [< $labels T >] ) ),*
147 }
148
149 pub use [< $name Choice >] :: {
150 $( $labels ),*
151 };
152 }
153 }
154}
155
156#[macro_export]
157#[allow(unused_macros)]
158
159macro_rules! match_extract {
160 ( $x:ident ;
161 ) => {
162 match $x {}
163 };
164 ( $x:ident ;
165 $label:ident
166 ) => {
167 $crate::macros::paste! {
168 match $x {
169 $crate::prelude::Sum::Inl ( [< $label:snake >] ) => {
170 $label ( [< $label:snake >] )
171 }
172 $crate::prelude::Sum::Inr ( bot ) => {
173 match bot { }
174 }
175 }
176 }
177 };
178 ( $x:ident ;
179 $label:ident, $( $labels:ident ),* $(,)?
180 ) => {
181 $crate::macros::paste! {
182 match $x {
183 $crate::prelude::Sum::Inl ( [< $label:snake >] ) => {
184 $label ( [< $label:snake >] )
185 }
186 $crate::prelude::Sum::Inr ( [< $label:snake _rest >] ) => {
187 $crate::match_extract! {
188 [< $label:snake _rest >] ;
189 $( $labels ),*
190 }
191 }
192 }
193 }
194 };
195}
196
197#[macro_export]
198macro_rules! define_extract_choice {
199 ( $name:ident ;
200 $( $labels:ident ),* $(,)?
201 ) => {
202 $crate::macros::paste! {
203 impl < $( [< $labels T >] ),* >
204 std::convert::From <
205 $crate::prelude::Sum![ $( [< $labels T >] ),* ]
206 >
207 for [< $name Choice >]
208 < $( [< $labels T >] ),* >
209 {
210 fn from
211 (row: $crate::prelude::Sum![ $( [< $labels T >] ),* ] )
212 -> Self
213 {
214 $crate::match_extract! {
215 row ;
216 $( $labels ),*
217 }
218 }
219 }
220 }
221 }
222}
223
224#[macro_export]
225macro_rules! define_choice {
226 ( $name:ident ;
227 $( $labels:ident : $protocols:ty ),+
228 $(,)?
229 ) => {
230 $crate::define_choice_protocol![ $name ;
231 $( $protocols ),*
232 ];
233
234 $crate::define_choice_labels![
235 $( $labels ),*
236 ];
237
238 $crate::define_choice_enum![ $name ;
239 $( $labels ),*
240 ];
241
242 $crate::define_extract_choice![ $name ;
243 $( $labels ),*
244 ];
245 };
246
247 ( $name:ident
248 < $( $types:ident ),+ $(,)? > ;
249 $( $labels:ident : $protocols:ty ),+
250 $(,)?
251 ) => {
252 $crate::define_choice_protocol![
253 $name < $( $types ),* > ;
254 $( $protocols ),*
255 ];
256
257 $crate::define_choice_labels![
258 $( $labels ),*
259 ];
260
261 $crate::define_choice_enum![ $name ;
262 $( $labels ),*
263 ];
264
265 $crate::define_extract_choice![ $name ;
266 $( $labels ),*
267 ];
268 };
269}
270
271#[macro_export]
272macro_rules! send_value {
273 ($val:expr, $cont:expr) => {
274 $crate::prelude::step(
275 async move { $crate::prelude::send_value($val, $cont) },
276 )
277 };
278}
279
280#[macro_export]
281macro_rules! send_value_to {
282 ($chan:expr, $val:expr, $cont:expr) => {
283 $crate::prelude::step(async move {
284 $crate::prelude::send_value_to($chan, $val, $cont)
285 })
286 };
287}
288
289#[macro_export]
290macro_rules! receive_value {
291 ( $var:ident => $body:expr ) => {
292 $crate::prelude::receive_value (
293 move | $var | {
294 $crate::prelude::step ( async move {
295 $body
296 })
297 }
298 )
299 };
300 ( ($var:ident $( : $type:ty )?) => $body:expr ) => {
301 $crate::prelude::receive_value (
302 move | $var $( : $type )* | {
303 $crate::prelude::step ( async move {
304 $body
305 })
306 }
307 )
308 }
309}
310
311#[macro_export]
312macro_rules! receive_value_from {
313 ( $chan:expr,
314 $var:ident => $body:expr
315 ) => {
316 $crate::prelude::receive_value_from (
317 $chan,
318 move | $var | {
319 $crate::prelude::step ( async move {
320 $body
321 })
322 }
323 )
324 };
325 ( $chan:expr,
326 ($var:ident $( : $type:ty )?) => $body:expr
327 ) => {
328 $crate::prelude::receive_value_from (
329 $chan,
330 move | $var $( : $type )* | {
331 $crate::prelude::step ( async move {
332 $body
333 })
334 }
335 )
336 }
337}
338
339#[macro_export]
340macro_rules! choose {
341 ($chan:expr, $label:ident, $cont:expr) => {
342 $crate::macros::paste! {
343 $crate::prelude::choose (
344 $chan,
345 [< $label Label >],
346 $cont
347 )
348 }
349 };
350}
351
352#[macro_export]
353macro_rules! offer_case {
354 ($label:ident, $cont:expr) => {
355 $crate::macros::paste! {
356 $crate::prelude::offer_case (
357 [< $label Label >],
358 $cont
359 )
360 }
361 };
362}
363
364#[macro_export]
365macro_rules! acquire_shared_session {
366 ($chan:expr, $var:ident => $body:expr) => {
367 $crate::prelude::acquire_shared_session($chan.clone(), move |$var| {
368 $crate::prelude::step(async move { $body })
369 })
370 };
371}
372
373#[macro_export]
374macro_rules! receive_channel {
375 ($var:ident => $body:expr) => {
376 $crate::prelude::receive_channel(move |$var| {
377 $crate::prelude::step(async move { $body })
378 })
379 };
380}
381
382#[macro_export]
383macro_rules! receive_channels {
384 ( ( $var:ident $(,)? ) => $body:expr ) => {
385 $crate::receive_channel!( $var => $body )
386 };
387 ( ( $var:ident, $( $vars:ident ),* $(,)? )
388 => $body:expr
389 ) => {
390 $crate::receive_channel! ( $var => {
391 $crate::receive_channels! (
392 ( $( $vars ),* ) =>
393 $body
394 )
395 })
396 };
397}
398
399#[macro_export]
400macro_rules! receive_channel_from {
401 ($chan:expr, $var:ident => $body:expr) => {
402 $crate::prelude::receive_channel_from($chan, move |$var| $body)
403 };
404}
405
406#[macro_export]
407macro_rules! include_session {
408 ($session:expr, $var:ident => $body:expr) => {
409 $crate::prelude::include_session($session, move |$var| {
410 $crate::prelude::step(async move { $body })
411 })
412 };
413}
414
415#[macro_export]
416macro_rules! terminate {
417 () => {
418 $crate::prelude::terminate()
419 };
420 ($cont:expr) => {
421 $crate::prelude::terminate_async(move || async move { $cont })
422 };
423}
424
425#[macro_export]
426macro_rules! wait {
427 ($chan:expr, $cont:expr) => {
428 $crate::prelude::wait($chan, $crate::prelude::step(async move { $cont }))
429 };
430}
431
432#[macro_export]
433macro_rules! wait_all {
434 ( [ $chan:expr $(,)? ],
435 $cont:expr
436 ) => {
437 $crate::prelude::wait! ( $chan, $cont )
438 };
439 ( [ $chan:expr, $( $chans:expr ),* $(,)? ],
440 $cont:expr
441 ) => {
442 $crate::prelude::wait! ( $chan,
443 $crate::prelude::wait_all! (
444 [ $( $chans ),* ],
445 $cont
446 )
447 )
448 };
449}
450
451#[macro_export]
452macro_rules! cut {
453 ( [ $( $labels:ty ),+ $(,)? ] ;
454 $cont1:expr ;
455 $var:ident => $cont2:expr
456 ) => {
457 < $crate::prelude::HList![ $( $labels ),* ]
458 as $crate::prelude::Cut < _ >
459 > :: cut (
460 $cont1,
461 move | $var | {
462 $crate::prelude::step ( async move {
463 $cont2
464 })
465 }
466 )
467 }
468}