Macro ergo::ch [−]
macro_rules! ch { [ $ send : ident <- ? $ value : expr ] => { ... }; [ $ send : ident <- $ value : expr ] => { ... }; [ <- ? $ recv : ident ] => { ... }; [ <- $ recv : ident ] => { ... }; [ ! <- ? $ recv : ident ] => { ... }; [ ! <- $ recv : ident ] => { ... }; }
Use with channels with ergonomic syntax and panic with helpful error messages when sending/receiving on a channel is invalid.
ch!(send <- 42)
for sending a value.let v = ch!(<- recv)
for receiving a value.ch!(! <- recv)
to wait for channels to close.<-?
for async operation support.
Blocking syntax:
ch!(send <- value)
: blocks until a value is sent, panics if all receivers are dropped.ch!(<- recv)
: blocks until a value is received, panics if all senders are dropped.ch!(! <- recv)
: blocks until all senders are dropped, panics if a value is received. Used for signaling.
This syntax works with both
crossbeam-channel
channels (which are exported by this crate) as well asstd::mspc
channels.
Note that these operations can deadlock if a channel is leaked.
Non-Blocking syntax:
ch!(send <-? value)
: returnsNone
if the value was sent,Some(value)
if the value was not sent. Panics if all receivers are dropped.ch!(<-? recv)
: returnsNone
if no value is received,Some(value)
if a value is received. Panics if all senders are dropped.ch!(! <-? recv)
: returnstrue
if there are still senders andfalse
if the seners have been dropped. Panics if a value is received. Use withwhile ch!(! <-? recv) { /* ... */ }
Non-Blocking syntax does not work with
std::mspc
channels.
Examples
Example: Using ergo::chan
channels
#[macro_use] extern crate ergo_sync; use ergo_sync::*; let (send, recv) = ch::bounded(3); ch!(send <- 4); ch!(send <- 7); ch!(send <- 42); assert_eq!(4, ch!(<- recv)); assert_eq!(7, ch!(<- recv)); let v = ch!(<- recv); assert_eq!(42, v); drop(send); // ch!(<- recv); // panics ch!(! <- recv); // succeeds
Example: Using std::mspc
channels
#[macro_use] extern crate ergo_sync; use std::sync::mpsc::sync_channel; let (send, recv) = sync_channel(3); ch!(send <- 4); ch!(send <- 7); ch!(send <- 42); assert_eq!(4, ch!(<- recv)); assert_eq!(7, ch!(<- recv)); let v = ch!(<- recv); assert_eq!(42, v); drop(send); // ch!(<- recv); // panics ch!(! <- recv); // succeeds
Example: using non-blocking syntax
#[macro_use] extern crate ergo_sync; use ergo_sync::*; let (send, recv) = ch::bounded(3); assert_eq!(None, ch!(<-? recv)); // no values sent yet assert!(ch!(send <-? 4).is_none()); assert_eq!(Some(4), ch!(<-? recv)); assert_eq!(None, ch!(<-? recv)); assert!(ch!(send <-? 7).is_none()); assert!(ch!(send <-? 42).is_none()); assert!(ch!(send <-? 1).is_none()); // further attempts return the value assert_eq!(Some(100), ch!(send <-? 100)); assert_eq!(Some(7), ch!(<-? recv)); assert_eq!(Some(42), ch!(<-? recv)); assert_eq!(Some(1), ch!(<-? recv)); assert_eq!(None, ch!(<-? recv)); assert!(ch!(! <-? recv)); // senders still exist drop(send); // ch!(<-? recv); // panics ch!(! <-? recv); // succeeds