Binary Internal Choice

Provider Rule: Offer Left

macro offer_case! <C, A, B> (
  Left,
  $cont: PartialSession<C, A>
) ->
  PartialSession<C, InternalChoice<Either<A, B>>>

Example

    let p: Session<
      InternalChoice<Either<ReceiveValue<String, End>, SendValue<u64, End>>>,
    > = offer_case!(
      Left,
      receive_value(move |name| {
        println!("Hello, {}!", name);
        terminate()
      })
    );

Provider Rule: Offer Right

macro offer_case! <C, A, B> (
  Right,
  $cont: PartialSession<C, B>
) ->
  PartialSession<C, InternalChoice<Either<A, B>>>

Example

    let p: Session<
      InternalChoice<Either<ReceiveValue<String, End>, SendValue<u64, End>>>,
    > = offer_case!(Right, send_value(42, terminate()));

Client Rule: Case

macro case! <N, C1, C2, C3, A1, A2, B> {
  $n: N;
  Left => $cont1: PartialSession<C2, B>,
  Right => $cont1: PartialSession<C3, B>,
} ->
  PartialSession<C1, B>
  • C1 is in the form HList[…, N: InternalChoice<Either<A1, A2>>, …].
  • C2 is in the form HList[…, N: A1, …], with the remaining elements being the same as in C1.
  • C3 is in the form HList[…, N: A2, …], with the remaining elements being the same as in C1.

Example

    let p: Session<
      ReceiveChannel<
        InternalChoice<Either<ReceiveValue<String, End>, SendValue<u64, End>>>,
        End,
      >,
    > = receive_channel(move |c| {
      case! { c;
        Left =>
          send_value_to(c,
            "Alice".to_string(),
            wait(c, terminate())),
        Right =>
          receive_value_from(c, move |x| {
            println!("{}", x);
            wait(c, terminate())
          })
      }
    });