use std::{fmt, io};
use tokio::signal::unix::{Signal, SignalKind, signal};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StopSignal {
Interrupt,
Terminate,
}
impl StopSignal {
pub fn exit_code(self) -> i32 {
match self {
Self::Interrupt => 130, Self::Terminate => 143, }
}
}
impl fmt::Display for StopSignal {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Interrupt => "SIGINT",
Self::Terminate => "SIGTERM",
})
}
}
pub struct ShutdownListener {
sigint: Signal,
sigterm: Signal,
}
impl ShutdownListener {
pub fn new() -> Result<Self, io::Error> {
Ok(Self {
sigint: signal(SignalKind::interrupt())?,
sigterm: signal(SignalKind::terminate())?,
})
}
pub async fn wait(&mut self) -> StopSignal {
tokio::select! {
_ = self.sigint.recv() => StopSignal::Interrupt,
_ = self.sigterm.recv() => StopSignal::Terminate,
}
}
}