2021-11-14 22:31:38 +01:00
|
|
|
use std::process;
|
|
|
|
|
2020-04-03 10:48:27 +02:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
2018-10-03 11:25:16 +02:00
|
|
|
pub enum ExitCode {
|
2019-09-13 22:26:27 +02:00
|
|
|
Success,
|
2021-08-14 17:57:01 +02:00
|
|
|
HasResults(bool),
|
2018-10-03 15:27:53 +02:00
|
|
|
GeneralError,
|
|
|
|
KilledBySigint,
|
2018-10-03 11:25:16 +02:00
|
|
|
}
|
|
|
|
|
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,
|
2021-08-14 17:57:01 +02:00
|
|
|
ExitCode::HasResults(has_results) => !has_results as i32,
|
2020-02-22 08:55:32 +01:00
|
|
|
ExitCode::GeneralError => 1,
|
|
|
|
ExitCode::KilledBySigint => 130,
|
2018-10-03 11:25:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-01-25 17:13:47 +01:00
|
|
|
|
|
|
|
impl ExitCode {
|
2021-07-27 08:38:09 +02:00
|
|
|
fn is_error(self) -> bool {
|
2021-08-14 17:57:01 +02:00
|
|
|
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) -> ! {
|
|
|
|
process::exit(self.into())
|
|
|
|
}
|
2020-01-25 17:13:47 +01:00
|
|
|
}
|
2020-02-22 09:08:07 +01:00
|
|
|
|
2021-08-21 22:43:17 +02:00
|
|
|
pub fn merge_exitcodes(results: impl IntoIterator<Item = ExitCode>) -> ExitCode {
|
|
|
|
if results.into_iter().any(ExitCode::is_error) {
|
2020-02-22 09:08:07 +01:00
|
|
|
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() {
|
2021-08-21 22:43:17 +02:00
|
|
|
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!(
|
2021-08-21 22:43:17 +02:00
|
|
|
merge_exitcodes([ExitCode::GeneralError]),
|
2020-02-22 10:39:03 +01:00
|
|
|
ExitCode::GeneralError
|
|
|
|
);
|
|
|
|
assert_eq!(
|
2021-08-21 22:43:17 +02:00
|
|
|
merge_exitcodes([ExitCode::KilledBySigint]),
|
2020-04-03 10:48:27 +02:00
|
|
|
ExitCode::GeneralError
|
|
|
|
);
|
|
|
|
assert_eq!(
|
2021-08-21 22:43:17 +02:00
|
|
|
merge_exitcodes([ExitCode::KilledBySigint, ExitCode::Success]),
|
2020-04-03 10:48:27 +02:00
|
|
|
ExitCode::GeneralError
|
|
|
|
);
|
|
|
|
assert_eq!(
|
2021-08-21 22:43:17 +02:00
|
|
|
merge_exitcodes([ExitCode::Success, ExitCode::GeneralError]),
|
2020-04-03 10:48:27 +02:00
|
|
|
ExitCode::GeneralError
|
|
|
|
);
|
|
|
|
assert_eq!(
|
2021-08-21 22:43:17 +02:00
|
|
|
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() {
|
2021-08-21 22:43:17 +02:00
|
|
|
assert_eq!(merge_exitcodes([ExitCode::Success]), ExitCode::Success);
|
2020-04-03 10:48:27 +02:00
|
|
|
assert_eq!(
|
2021-08-21 22:43:17 +02:00
|
|
|
merge_exitcodes([ExitCode::Success, ExitCode::Success]),
|
2020-04-03 10:48:27 +02:00
|
|
|
ExitCode::Success
|
|
|
|
);
|
2020-02-22 10:39:03 +01:00
|
|
|
}
|
|
|
|
}
|