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
use crate::prelude::*;
use std::sync::atomic::{AtomicBool, Ordering};
pub struct InterruptibleStream<V> {
inner: Box<dyn Iterator<Item = V> + Send + Sync>,
interrupt_signal: Arc<AtomicBool>,
}
impl<V> InterruptibleStream<V> {
pub fn new<S>(inner: S, interrupt_signal: Arc<AtomicBool>) -> InterruptibleStream<V>
where
S: Iterator<Item = V> + Send + Sync + 'static,
{
InterruptibleStream {
inner: Box::new(inner),
interrupt_signal,
}
}
}
impl<V> Iterator for InterruptibleStream<V> {
type Item = V;
fn next(&mut self) -> Option<Self::Item> {
if self.interrupt_signal.load(Ordering::SeqCst) {
None
} else {
self.inner.next()
}
}
}
pub trait Interruptible<V> {
fn interruptible(self, ctrl_c: Arc<AtomicBool>) -> InterruptibleStream<V>;
}
impl<S, V> Interruptible<V> for S
where
S: Iterator<Item = V> + Send + Sync + 'static,
{
fn interruptible(self, ctrl_c: Arc<AtomicBool>) -> InterruptibleStream<V> {
InterruptibleStream::new(self, ctrl_c)
}
}