1use crossbeam_channel::{unbounded, Sender, Receiver, TryRecvError};
2
3#[derive(Debug, Clone, Copy)]
4pub enum CtrlCResponse {
5 Quit,
6 Continue,
7 Error,
8}
9
10#[derive(Debug, Clone)]
11pub struct CtrlCHandler {
12 rx: Receiver<CtrlCResponse>,
13 tx: Sender<CtrlCResponse>,
14}
15
16impl CtrlCHandler {
17 pub fn new() -> Self {
18 let (tx, rx) = unbounded::<CtrlCResponse>();
19 let tx_clone = tx.clone();
20 ctrlc::set_handler(move || tx_clone.send(CtrlCResponse::Quit).expect("Could not send signal on channel."))
21 .expect("Error setting Ctrl-C handler");
22 Self {
23 rx: rx,
24 tx: tx.clone(),
25 }
26 }
27 pub fn respond(&self) -> CtrlCResponse {
29 match self.rx.try_recv() {
30 Ok(rx) => rx,
31 Err(TryRecvError::Empty) => CtrlCResponse::Continue,
32 Err(TryRecvError::Disconnected) => CtrlCResponse::Error,
33 }
34 }
35 pub fn send_quit(&self) {
37 self.tx.clone().send(CtrlCResponse::Quit).unwrap();
38 }
39 pub fn should_continue(&self) -> bool {
41 if let CtrlCResponse::Continue = self.respond() {
42 true
43 } else {
44 false
45 }
46 }
47 pub fn get_tx(&self) -> Sender<CtrlCResponse> {
49 self.tx.clone()
50 }
51}