1#![cfg_attr(not(feature = "std"), no_std)]
10
11use core::fmt::Display;
12
13use raw::RawExitCode;
14
15pub mod raw;
16pub mod unix;
17pub mod windows;
18
19#[allow(dead_code)]
21mod doc_tests {
22 #[doc = include_str!("../README.md")]
23 struct Readme;
24}
25
26#[derive(Clone, Copy, Debug, PartialEq, Eq)]
28#[non_exhaustive]
29pub enum ProcResult {
30 Unix(unix::WaitStatus),
32
33 Windows(windows::ExitCode),
35}
36
37impl ProcResult {
38 pub fn ok(&self) -> Result<(), Self> {
44 if self.is_success() {
45 Ok(())
46 } else {
47 Err(*self)
48 }
49 }
50
51 #[must_use]
53 pub fn is_success(&self) -> bool {
54 match self {
55 ProcResult::Unix(status) => status.exit_code().is_some_and(|code| code.is_success()),
56 ProcResult::Windows(code) => code.is_success(),
57 }
58 }
59
60 #[must_use]
62 pub fn is_failure(&self) -> bool {
63 !self.is_success()
64 }
65}
66
67#[cfg(feature = "std")]
68impl Display for ProcResult {
69 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
70 match self {
71 Self::Unix(status) => write!(f, "Unix exit status: {}", status.to_raw()),
72 Self::Windows(code) => write!(f, "Windows exit code: {}", code.to_raw()),
73 }
74 }
75}
76
77impl core::error::Error for ProcResult {}
78
79#[cfg(feature = "std")]
80impl From<std::process::ExitStatus> for ProcResult {
81 #[allow(unreachable_code)]
82 fn from(status: std::process::ExitStatus) -> Self {
83 #[cfg(unix)]
84 {
85 let err: unix::WaitStatus = status.into();
86 return Self::Unix(err);
87 }
88 #[cfg(windows)]
89 {
90 let err: windows::ExitCode = status.into();
91 return Self::Windows(err);
92 }
93 panic!("Cannot convert exit status to error on this platform");
94 }
95}