[−][src]Macro dialectic::offer
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. - 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::*; use dialectic::constants::*; type GiveOrTake = Choose<(Send<i64>, Recv<String>)>; let (c1, c2) = GiveOrTake::channel(|| backend::mpsc::channel(1)); // Spawn a thread to offer a choice let t1 = tokio::spawn(async move { offer! { c2 => { c2.recv().await?; }, { c2.send("Hello!".to_string()).await?; }, } Ok::<_, backend::mpsc::Error>(()) }); // Choose to send an integer c1.choose(_0).await?.send(42).await?; // Wait for the offering thread to finish t1.await??;
Errors
The generated code may result in the Transmit::Error
of the underlying connection, as well
as OutOfRangeChoice
in the case where the other side of the connection breaks the protocol
and selects a choice that does not exist. If the other side of the channel is also using this
session type, that case is impossible.
Alternatively, you may specify an optional clause to handle protocol violations where the other side signals an invalid choice. In the example above, we could choose to immediately panic in that scenario:
offer! { c2 => { c2.recv().await?; }, { c2.send("Hello!".to_string()).await?; }, ? => panic!("Protocol violation!"), }