rosrust/util/
killable_channel.rs

1use super::kill;
2pub use super::kill::KillMode;
3use crossbeam::channel;
4pub use crossbeam::channel::Sender;
5
6pub struct Receiver<T> {
7    pub data_rx: channel::Receiver<T>,
8    pub kill_rx: kill::Receiver,
9}
10
11impl<T> Iterator for Receiver<T> {
12    type Item = T;
13
14    fn next(&mut self) -> Option<Self::Item> {
15        channel::select! {
16            recv(self.data_rx) -> msg => msg.ok(),
17            recv(self.kill_rx.kill_rx) -> _ => None,
18        }
19    }
20}
21
22pub type Killer = kill::Sender;
23
24#[allow(dead_code)]
25pub enum SendMode {
26    Sync,
27    Bounded(usize),
28    Unbounded,
29}
30
31impl SendMode {
32    fn into_channel<T>(self) -> (channel::Sender<T>, channel::Receiver<T>) {
33        match self {
34            SendMode::Sync => channel::bounded(0),
35            SendMode::Bounded(queue_size) => channel::bounded(queue_size),
36            SendMode::Unbounded => channel::unbounded(),
37        }
38    }
39}
40
41pub fn channel<T>(send_mode: SendMode, kill_mode: KillMode) -> (Killer, Sender<T>, Receiver<T>) {
42    let (data_tx, data_rx) = send_mode.into_channel();
43    let (kill_tx, kill_rx) = kill::channel(kill_mode);
44    (kill_tx, data_tx, Receiver { data_rx, kill_rx })
45}