fd/src/exit_codes.rs

95 lines
2.4 KiB
Rust
Raw Normal View History

2021-11-14 22:31:38 +01:00
use std::process;
#[cfg(unix)]
use nix::sys::signal::{raise, signal, SigHandler, Signal};
2022-09-11 21:29:43 +02:00
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExitCode {
Success,
HasResults(bool),
GeneralError,
KilledBySigint,
}
2021-07-27 08:38:09 +02:00
impl From<ExitCode> for i32 {
fn from(code: ExitCode) -> Self {
match code {
2020-02-22 08:55:32 +01:00
ExitCode::Success => 0,
ExitCode::HasResults(has_results) => !has_results as i32,
2020-02-22 08:55:32 +01:00
ExitCode::GeneralError => 1,
ExitCode::KilledBySigint => 130,
}
}
}
impl ExitCode {
2021-07-27 08:38:09 +02:00
fn is_error(self) -> bool {
i32::from(self) != 0
2020-02-22 09:01:52 +01:00
}
2021-11-14 22:31:38 +01:00
/// Exit the process with the appropriate code.
pub fn exit(self) -> ! {
#[cfg(unix)]
if self == ExitCode::KilledBySigint {
// Get rid of the SIGINT handler, if present, and raise SIGINT
unsafe {
if signal(Signal::SIGINT, SigHandler::SigDfl).is_ok() {
let _ = raise(Signal::SIGINT);
}
}
}
2021-11-14 22:31:38 +01:00
process::exit(self.into())
}
}
pub fn merge_exitcodes(results: impl IntoIterator<Item = ExitCode>) -> ExitCode {
if results.into_iter().any(ExitCode::is_error) {
return ExitCode::GeneralError;
}
ExitCode::Success
}
2020-02-22 10:39:03 +01:00
#[cfg(test)]
mod tests {
use super::*;
#[test]
2020-04-03 10:48:27 +02:00
fn success_when_no_results() {
assert_eq!(merge_exitcodes([]), ExitCode::Success);
2020-02-22 10:39:03 +01:00
}
#[test]
2020-04-03 10:48:27 +02:00
fn general_error_if_at_least_one_error() {
2020-02-22 10:39:03 +01:00
assert_eq!(
merge_exitcodes([ExitCode::GeneralError]),
2020-02-22 10:39:03 +01:00
ExitCode::GeneralError
);
assert_eq!(
merge_exitcodes([ExitCode::KilledBySigint]),
2020-04-03 10:48:27 +02:00
ExitCode::GeneralError
);
assert_eq!(
merge_exitcodes([ExitCode::KilledBySigint, ExitCode::Success]),
2020-04-03 10:48:27 +02:00
ExitCode::GeneralError
);
assert_eq!(
merge_exitcodes([ExitCode::Success, ExitCode::GeneralError]),
2020-04-03 10:48:27 +02:00
ExitCode::GeneralError
);
assert_eq!(
merge_exitcodes([ExitCode::GeneralError, ExitCode::KilledBySigint]),
2020-02-22 10:39:03 +01:00
ExitCode::GeneralError
);
}
#[test]
2020-04-03 10:48:27 +02:00
fn success_if_no_error() {
assert_eq!(merge_exitcodes([ExitCode::Success]), ExitCode::Success);
2020-04-03 10:48:27 +02:00
assert_eq!(
merge_exitcodes([ExitCode::Success, ExitCode::Success]),
2020-04-03 10:48:27 +02:00
ExitCode::Success
);
2020-02-22 10:39:03 +01:00
}
}