#[macro_use]
extern crate kernel;
#[cfg(feature = "chan_select")]
use std::thread::spawn;
#[cfg(feature = "chan_select")]
use std::borrow::ToOwned;
#[cfg(feature = "chan_select")]
use kernel::session_types::*;
#[cfg(feature = "chan_select")]
macro_rules! recv_assert_eq_close(
($e:expr, $rx:ident.recv())
=>
({
let (c, v) = $rx.recv();
assert_eq!($e, v);
c.close();
})
);
#[cfg(feature = "chan_select")]
#[test]
fn chan_select_simple() {
let (tcs, rcs) = session_channel();
let (tcu, rcu) = session_channel();
send_str(tcs);
let index = {
let mut sel = ChanSelect::new();
sel.add_recv(&rcs); sel.add_recv(&rcu); sel.wait() };
assert_eq!(0, index);
recv_assert_eq_close!("Hello, World!".to_owned(), rcs.recv());
let (tcs, rcs) = session_channel();
send_usize(tcu);
let index = {
let mut sel = ChanSelect::new();
sel.add_recv(&rcs);
sel.add_recv(&rcu);
sel.wait()
};
assert_eq!(1, index);
recv_assert_eq_close!(42, rcu.recv());
send_str(tcs);
recv_assert_eq_close!("Hello, World!".to_owned(), rcs.recv());
}
#[cfg(feature = "chan_select")]
#[test]
fn chan_select_add_ret() {
enum ChanToRead {
Str,
Usize,
}
let (tcs, rcs) = session_channel();
let (tcu, rcu) = session_channel();
spawn(move || send_str(tcs));
let chan_to_read = {
let mut sel = ChanSelect::new();
sel.add_recv_ret(&rcs, ChanToRead::Str); sel.add_recv_ret(&rcu, ChanToRead::Usize); sel.wait() };
send_usize(tcu);
match chan_to_read {
ChanToRead::Str => {
recv_assert_eq_close!("Hello, World!".to_owned(), rcs.recv());
recv_assert_eq_close!(42, rcu.recv());
}
ChanToRead::Usize => {
panic!("Unexpected read of usize chan before str chan!");
}
}
}
#[cfg(feature = "chan_select")]
fn send_str(c: Chan<(), Send<String, Eps>>) {
c.send("Hello, World!".to_string()).close();
}
#[cfg(feature = "chan_select")]
fn send_usize(c: Chan<(), Send<usize, Eps>>) {
c.send(42).close();
}