#[macro_export]
macro_rules! select {
(@build [$($arms:tt)*] [$($cancelled:tt)*] $val:ident = $rx:expr => $body:expr, $($rest:tt)*) => {
$crate::select!(@build [
$($arms)*
recv($rx.as_crossbeam()) -> __msg => {
let $val = match $crate::channel::__task_cancelled() {
true => $rx.__cancelled_receive(),
false => __msg.map_err(|_| $crate::RuntimeError::ChannelClosed),
};
$body
},
] [$($cancelled)*] $($rest)*)
};
(@build [$($arms:tt)*] [$($cancelled:tt)*] timeout($dur:expr) => $body:expr $(,)?) => {{
let __duration = $dur;
let __started = std::time::Instant::now();
match (
$crate::channel::__task_cancelled(),
$crate::channel::__task_cancel_receiver(),
) {
(true, _) => { $($cancelled)* },
(false, Some(__cancel)) => {
$crate::__private::crossbeam_channel::select! {
$($arms)*
recv(__cancel) -> __cancelled_signal => match __cancelled_signal {
Ok(()) => { $($cancelled)* },
Err(_) => $crate::__private::crossbeam_channel::select! {
$($arms)*
default(__duration.saturating_sub(__started.elapsed())) => { $body }
},
},
default(__duration) => { $body }
}
}
(false, None) => $crate::__private::crossbeam_channel::select! {
$($arms)*
default(__duration) => { $body }
},
}
}};
(@build [$($arms:tt)*] [$($cancelled:tt)*]) => {{
match (
$crate::channel::__task_cancelled(),
$crate::channel::__task_cancel_receiver(),
) {
(true, _) => { $($cancelled)* },
(false, Some(__cancel)) => {
$crate::__private::crossbeam_channel::select! {
$($arms)*
recv(__cancel) -> __cancelled_signal => match __cancelled_signal {
Ok(()) => { $($cancelled)* },
Err(_) => $crate::__private::crossbeam_channel::select! {
$($arms)*
},
},
}
}
(false, None) => $crate::__private::crossbeam_channel::select! {
$($arms)*
},
}
}};
($val:ident = $rx:expr => $body:expr, $($rest:tt)*) => {{
let __first_receiver = &$rx;
$crate::select!(@build [
recv(__first_receiver.as_crossbeam()) -> __msg => {
let $val = match $crate::channel::__task_cancelled() {
true => __first_receiver.__cancelled_receive(),
false => __msg.map_err(|_| $crate::RuntimeError::ChannelClosed),
};
$body
},
] [{
let $val = __first_receiver.__cancelled_receive();
$body
}] $($rest)*)
}};
}