nu_stream/
interruptible.rs

1use crate::prelude::*;
2use std::sync::atomic::{AtomicBool, Ordering};
3
4pub struct InterruptibleStream<V> {
5    inner: Box<dyn Iterator<Item = V> + Send + Sync>,
6    interrupt_signal: Arc<AtomicBool>,
7}
8
9impl<V> InterruptibleStream<V> {
10    pub fn new<S>(inner: S, interrupt_signal: Arc<AtomicBool>) -> InterruptibleStream<V>
11    where
12        S: Iterator<Item = V> + Send + Sync + 'static,
13    {
14        InterruptibleStream {
15            inner: Box::new(inner),
16            interrupt_signal,
17        }
18    }
19}
20
21impl<V> Iterator for InterruptibleStream<V> {
22    type Item = V;
23
24    fn next(&mut self) -> Option<Self::Item> {
25        if self.interrupt_signal.load(Ordering::SeqCst) {
26            None
27        } else {
28            self.inner.next()
29        }
30    }
31}
32
33pub trait Interruptible<V> {
34    fn interruptible(self, ctrl_c: Arc<AtomicBool>) -> InterruptibleStream<V>;
35}
36
37impl<S, V> Interruptible<V> for S
38where
39    S: Iterator<Item = V> + Send + Sync + 'static,
40{
41    fn interruptible(self, ctrl_c: Arc<AtomicBool>) -> InterruptibleStream<V> {
42        InterruptibleStream::new(self, ctrl_c)
43    }
44}