[][src]Macro dialectic::offer

macro_rules! offer {
    (
        $chan:ident => { $($t:tt)* }
    ) => { ... };
    (
        @branches $branch:ident, $chan:ident, $n:ty, $(,)?
    ) => { ... };
    (
        @branches $branch:ident, $chan:ident, $n:ty, $label:expr => $code:expr $(,)?
    ) => { ... };
    (
        @branches $branch:ident, $chan:ident, $n:ty, $label:expr => $code:expr, $($t:tt)+
    ) => { ... };
}

Offer a set of different protocols, allowing the other side of the channel to choose with which one to proceed. This macro only works in a Try context, i.e. somewhere the ? operator would make sense to use.

Notes

  • You must specify exactly as many branches as there are options in the type of the Offer to which this expression corresponds, and they must be in the same order as the choices are in the tuple Offered.
  • In the body of each branch, the identifier for the channel is rebound to have the session type corresponding to that branch.
  • To use offer! as an expression, ensure the type of every branch matches.

Examples

use dialectic::prelude::*;
use dialectic::backend::mpsc;

type GiveOrTake = Choose<(Send<i64>, Recv<String>)>;

let (c1, c2) = GiveOrTake::channel(|| mpsc::channel(1));

// Spawn a thread to offer a choice
let t1 = tokio::spawn(async move {
    offer!(c2 => {
        _0 => { c2.recv().await?; },
        _1 => { c2.send("Hello!".to_string()).await?; },
    });
    Ok::<_, mpsc::Error>(())
});

// Choose to send an integer
c1.choose(_0).await?.send(42).await?;

// Wait for the offering thread to finish
t1.await??;