use crate::cmd::CmdLineRunner;
use eyre::Report;
#[cfg(unix)]
use nix::sys::signal::SIGTERM;
use std::error::Error;
use std::fmt::{self, Display, Formatter};
#[derive(Debug)]
struct ExitRequest {
code: i32,
}
impl Display for ExitRequest {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "exit with status {}", self.code)
}
}
impl Error for ExitRequest {}
pub(crate) fn request(code: i32) -> Report {
Report::new(ExitRequest { code })
}
pub(crate) fn requested_exit_code(err: &Report) -> Option<i32> {
err.downcast_ref::<ExitRequest>().map(|exit| exit.code)
}
pub(crate) fn kill_all() {
#[cfg(unix)]
CmdLineRunner::kill_all(SIGTERM);
#[cfg(windows)]
CmdLineRunner::kill_all();
}
pub(crate) fn status(code: i32) -> std::process::ExitCode {
debug!("exiting with code: {code}");
std::process::ExitCode::from(code as u8)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn finds_requested_exit_code_through_context() {
let err = request(42).wrap_err("context");
assert_eq!(requested_exit_code(&err), Some(42));
}
}