ferrite_session/
macros.rs

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}