1#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum ExitStatusKind {
13 Code(i32),
15 Signal(String),
17 Unknown,
20}
21
22impl std::fmt::Display for ExitStatusKind {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 match self {
25 ExitStatusKind::Code(c) => write!(f, "{c}"),
26 ExitStatusKind::Signal(s) => write!(f, "signal {s}"),
27 ExitStatusKind::Unknown => write!(f, "<unknown>"),
28 }
29 }
30}
31
32pub fn exit_status_kind(status: std::process::ExitStatus) -> ExitStatusKind {
36 if let Some(code) = status.code() {
37 return ExitStatusKind::Code(code);
38 }
39 #[cfg(unix)]
40 {
41 use std::os::unix::process::ExitStatusExt;
42 if let Some(sig) = status.signal() {
43 return ExitStatusKind::Signal(sig.to_string());
44 }
45 }
46 ExitStatusKind::Unknown
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn display_renders_each_variant() {
55 assert_eq!(ExitStatusKind::Code(0).to_string(), "0");
56 assert_eq!(ExitStatusKind::Code(-1).to_string(), "-1");
57 assert_eq!(
58 ExitStatusKind::Signal("11".to_owned()).to_string(),
59 "signal 11"
60 );
61 assert_eq!(ExitStatusKind::Unknown.to_string(), "<unknown>");
62 }
63
64 #[cfg(unix)]
65 #[test]
66 fn classifies_unix_wait_statuses() {
67 use std::os::unix::process::ExitStatusExt;
68 use std::process::ExitStatus;
69 assert_eq!(
72 exit_status_kind(ExitStatus::from_raw(0)),
73 ExitStatusKind::Code(0)
74 );
75 assert_eq!(
76 exit_status_kind(ExitStatus::from_raw(2 << 8)),
77 ExitStatusKind::Code(2)
78 );
79 assert_eq!(
80 exit_status_kind(ExitStatus::from_raw(9)),
81 ExitStatusKind::Signal("9".to_owned())
82 );
83 assert_eq!(
86 exit_status_kind(ExitStatus::from_raw(0x7f)),
87 ExitStatusKind::Unknown
88 );
89 }
90
91 #[cfg(windows)]
92 #[test]
93 fn classifies_windows_exit_codes() {
94 use std::os::windows::process::ExitStatusExt;
95 use std::process::ExitStatus;
96 assert_eq!(
97 exit_status_kind(ExitStatus::from_raw(0)),
98 ExitStatusKind::Code(0)
99 );
100 assert_eq!(
101 exit_status_kind(ExitStatus::from_raw(2)),
102 ExitStatusKind::Code(2)
103 );
104 }
105}