[][src]Macro session_types::chan_select

macro_rules! chan_select {
    (
        $(($c:ident, $name:pat) = $rx:ident.recv() => $code:expr),+
    ) => { ... };
    (
        $($res:ident = $rx:ident.offer() => { $($t:tt)+ }),+
    ) => { ... };
}

This macro plays the same role as the select! macro does for Receivers.

It also supports a second form with Offers (see the example below).

Examples

extern crate session_types;
use session_types::*;
use std::thread::spawn;

fn send_str(c: Chan<(), Send<String, Eps>>) {
    c.send("Hello, World!".to_string()).close();
}

fn send_usize(c: Chan<(), Send<usize, Eps>>) {
    c.send(42).close();
}

fn main() {
    let (tcs, rcs) = session_channel();
    let (tcu, rcu) = session_channel();

    // Spawn threads
    spawn(move|| send_str(tcs));
    spawn(move|| send_usize(tcu));

    chan_select! {
        (c, s) = rcs.recv() => {
            assert_eq!("Hello, World!".to_string(), s);
            c.close();
            rcu.recv().0.close();
        },
        (c, i) = rcu.recv() => {
            assert_eq!(42, i);
            c.close();
            rcs.recv().0.close();
        }
    }
}
extern crate session_types;
extern crate rand;

use std::thread::spawn;
use session_types::*;

type Igo = Choose<Send<String, Eps>, Send<u64, Eps>>;
type Ugo = Offer<Recv<String, Eps>, Recv<u64, Eps>>;

fn srv(chan_one: Chan<(), Ugo>, chan_two: Chan<(), Ugo>) {
    let _ign;
    chan_select! {
        _ign = chan_one.offer() => {
            String => {
                let (c, s) = chan_one.recv();
                assert_eq!("Hello, World!".to_string(), s);
                c.close();
                match chan_two.offer() {
                    Left(c) => c.recv().0.close(),
                    Right(c) => c.recv().0.close(),
                }
            },
            Number => {
                chan_one.recv().0.close();
                match chan_two.offer() {
                    Left(c) => c.recv().0.close(),
                    Right(c) => c.recv().0.close(),
                }
            }
        },
        _ign = chan_two.offer() => {
            String => {
                chan_two.recv().0.close();
                match chan_one.offer() {
                    Left(c) => c.recv().0.close(),
                    Right(c) => c.recv().0.close(),
                }
            },
            Number => {
                chan_two.recv().0.close();
                match chan_one.offer() {
                    Left(c) => c.recv().0.close(),
                    Right(c) => c.recv().0.close(),
                }
            }
        }
    }
}

fn cli(c: Chan<(), Igo>) {
    c.sel1().send("Hello, World!".to_string()).close();
}

fn main() {
    let (ca1, ca2) = session_channel();
    let (cb1, cb2) = session_channel();

    cb2.sel2().send(42).close();

    spawn(move|| cli(ca2));

    srv(ca1, cb1);
}