#[macro_export]
macro_rules! nu_select {
($($name:pat = $rx:expr => $code:expr),+) => ({
nu_select!{ $($name = $rx, recv => $code),+ }
});
($($name:pat = $rx:expr, $meth:ident => $code:expr),+) => ({
use rustrt::local::Local;
use rustrt::task::Task;
use sync::comm::Packet;
$(
if (&$rx as &Packet).can_recv() {
let $name = $rx.$meth();
$code
}
)else+
else {
let mut started_count = 0;
{
let packets = [ $( &$rx as &Packet, )+ ];
let task: Box<Task> = Local::take();
task.deschedule(packets.len(), |task| {
match packets[started_count].start_selection(task) {
Ok(()) => {
started_count += 1;
Ok(())
}
Err(task) => Err(task)
}
});
}
let mut i = 0;
let ret = $(
if { i += 1; i <= started_count } &&
($rx.abort_selection() || i == started_count) {
let $name = $rx.$meth();
$code
})else+
else {
fail!("we didn't find the ready receiver, but we should have had one");
};
$(if i > 0 {
i -= 1;
} else {
$rx.abort_selection();
})+
let _ = i; ret
}
})
}
#[macro_export]
macro_rules! user_enum {
($(#[$attr:meta])* pub enum $name:ident { $(#[$doc:meta] $elem:ident <-> $txt:expr),* }) => (
$(#[$attr])*
pub enum $name {
$(#[$doc] $elem),*
}
impl ::std::fmt::Debug for $name {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.pad(match *self {
$($name::$elem => $txt),*
})
}
}
impl ::std::fmt::Display for $name {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.pad(match *self {
$($name::$elem => $txt),*
})
}
}
impl ::serde::Deserialize for $name {
#[inline]
fn deserialize<D>(d: &mut D) -> Result<$name, D::Error>
where D: ::serde::Deserializer
{
struct Visitor;
impl ::serde::de::Visitor for Visitor {
type Value = $name;
fn visit_string<E>(&mut self, v: String) -> Result<$name, E>
where E: ::serde::de::Error
{
self.visit_str(&v)
}
fn visit_str<E>(&mut self, s: &str) -> Result<$name, E>
where E: ::serde::de::Error
{
$( if s == $txt { Ok($name::$elem) } )else*
else { Err(::serde::de::Error::syntax(stringify!($name))) }
}
}
d.visit(Visitor)
}
}
impl ::serde::Serialize for $name {
fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
where S: ::serde::Serializer
{
s.visit_str(&self.to_string())
}
}
);
}