1use std::process;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum ExitStatus {
5 Exited(i32),
6 #[cfg(unix)]
7 Signaled {
8 signal: i32,
9 core_dumped: bool,
10 },
11}
12
13impl ExitStatus {
14 pub fn code(self) -> i32 {
15 match self {
16 ExitStatus::Exited(code) => code,
17 #[cfg(unix)]
18 ExitStatus::Signaled { signal, .. } => -signal,
19 }
20 }
21}
22
23#[cfg(unix)]
24impl From<process::ExitStatus> for ExitStatus {
25 fn from(status: process::ExitStatus) -> Self {
26 use std::os::unix::process::ExitStatusExt;
27
28 match (status.code(), status.signal()) {
29 (Some(code), None) => Self::Exited(code),
30 (None, Some(signal)) => Self::Signaled {
31 signal,
32 core_dumped: status.core_dumped(),
33 },
34 (None, None) => {
35 debug_assert!(false, "ExitStatus should have either a code or a signal");
36 Self::Exited(-1)
37 }
38 (Some(code), Some(signal)) => {
39 debug_assert!(
42 false,
43 "ExitStatus cannot have both a code ({code}) and a signal ({signal})"
44 );
45 Self::Signaled {
46 signal,
47 core_dumped: status.core_dumped(),
48 }
49 }
50 }
51 }
52}
53
54#[cfg(not(unix))]
55impl From<process::ExitStatus> for ExitStatus {
56 fn from(status: process::ExitStatus) -> Self {
57 let code = status.code();
58 debug_assert!(
59 code.is_some(),
60 "`ExitStatus::code` cannot return `None` on windows"
61 );
62 Self::Exited(code.unwrap_or(-1))
63 }
64}