Macro dialectic::offer[][src]

offer!() { /* proc-macro */ }

The offer! macro offers a set of different protocols, allowing the other side of the channel to choose with which one to proceed.

Each invocation of the offer! macro on some Chan<S, Tx, Rx> returns Result<_, Rx::Error>, which will be an error if the receiving transport end Rx failed to receive the choice made by the other party. Otherwise, it returns whatever type is returned by each of its branches (which means that each branch must have the same type).

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, so you can proceed with its session.

Examples

use dialectic::prelude::*;
use dialectic_tokio_mpsc as mpsc;

type GiveOrTake = Session! {
    choose {
        0 => send i64,
        1 => recv String,
    }
};

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

// Spawn a thread to offer a choice
let t1 = tokio::spawn(async move {
    offer!(in 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??;