1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/**
Wrapper around `Receiver<DownMsg<T>>::recv`, meant to be used in a loop:

- if `Stop` or `Err` is received, breaks from the parent loop
- if `Pause` or `Continue` are received, do nothing
- if `Other(x)` is received, returns `x`

# Example

```
# use worker_pool::*;
# let mut pool: WorkerPool<(), usize> = WorkerPool::new(100);
pool.execute(|_tx, rx| {
    loop {
        let msg = worker_pool::recv_break!(rx);
        // Do something with msg
    }
});
# pool.broadcast(DownMsg::Other(10));
# pool.stop_and_join();
```
*/
#[macro_export]
macro_rules! recv_break {
    ( $rx:tt ) => {{
        let res = loop {
            match $rx.recv() {
                Ok(DownMsg::Stop) => break None,
                Ok(DownMsg::Pause) => {}
                Ok(DownMsg::Continue) => {},
                Ok(DownMsg::Other(x)) => break Some(x),
                Err(_) => break None
            }
        };

        match res {
            Some(x) => x,
            None => break
        }
    }}
}
/**
Wrapper around `Receiver<DownMsg<T>>::try_recv`, meant to be used in a loop:

- if `Stop` or `Disconnected` is received, breaks from the parent loop
- if `Pause` is received, then block until `Continue` is received; any `Other` message will be ignored between the two
- if `Continue` or `Empty` is received, returns `None`
- if `Other(x)` is received, returns `Some(x)`

# Example

```
# use worker_pool::*;
# let mut pool: WorkerPool<(), usize> = WorkerPool::new(100);
pool.execute(|_tx, rx| {
    # let mut count = 0;
    loop {
        if let Some(msg) = worker_pool::try_recv_break!(rx) {
            // Handle msg
            # count = msg;
        } else {
            // Do something else in the meantime
            # count += 1;
        }
    }
});
# pool.broadcast(DownMsg::Other(10));
# pool.stop_and_join();
```
*/
#[macro_export]
macro_rules! try_recv_break {
    ( $rx:tt ) => {{
        match $rx.try_recv() {
            Ok(DownMsg::Stop) => break,
            Ok(DownMsg::Pause) => {
                let break_loop = loop {
                    match $rx.recv() {
                        Ok(DownMsg::Stop) => break true,
                        Ok(DownMsg::Pause) => {}
                        Ok(DownMsg::Continue) => break false,
                        Ok(DownMsg::Other(x)) => {},
                        Err(_) => break true
                    }
                };

                if break_loop {
                    break
                } else {
                    None
                }
            }
            Ok(DownMsg::Continue) => None,
            Ok(DownMsg::Other(x)) => Some(x),
            Err(TryRecvError::Disconnected) => break,
            Err(TryRecvError::Empty) => None,
        }
    }}
}