Macro offer

Source
macro_rules! offer {
    (
        $id:ident, $timeout:expr, $branch:ident => $code:expr, $($t:tt)+
    ) => { ... };
    (
        $id:ident, $timeout:expr, $branch:ident => $code:expr
    ) => { ... };
}
Expand description

This macro is convenient for server-like protocols of the form:

Offer<A, Offer<B, Offer<C, ... >>>

ยงExamples

Assume we have a protocol Offer<Recv<u64, Eps>, Offer<Recv<String, Eps>,Eps>>> we can use the offer! macro as follows:

use async_session_types::offer;
use async_session_types::*;
use std::time::Duration;

struct Bye;

async fn srv(c: Chan<Offer<Recv<u64, Eps>, Offer<Recv<String, Eps>, Recv<Bye, Eps>>>, (), DynMessage>) -> SessionResult<()> {
    let t = Duration::from_secs(1);
    offer! { c, t,
        Number => {
            let (c, n) = c.recv(t).await?;
            assert_eq!(42, n);
            c.close()
        },
        String => {
            c.recv(t).await?.0.close()
        },
        Quit => {
            c.recv(t).await?.0.close()
        }
    }
}

async fn cli(c: Chan<Choose<Send<u64, Eps>, Choose<Send<String, Eps>, Send<Bye, Eps>>>, (), DynMessage>) -> SessionResult<()>{
    c.sel1().send(42)?.close()
}

#[tokio::main]
async fn main() {
    let (s, c) = session_channel();
    tokio::spawn(cli(c));
    srv(s).await.unwrap();
}

The identifiers on the left-hand side of the arrows have no semantic meaning, they only provide a meaningful name for the reader.