#![cfg_attr(not(feature = "std"), no_std)]
use core::fmt::Display;
use raw::RawExitCode;
pub mod raw;
pub mod unix;
pub mod windows;
#[allow(dead_code)]
mod doc_tests {
#[doc = include_str!("../README.md")]
struct Readme;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum ProcResult {
Unix(unix::WaitStatus),
Windows(windows::ExitCode),
}
impl ProcResult {
#[cfg(all(feature = "std", unix))]
#[must_use]
pub fn default_success() -> Self {
Self::Unix(unix::WaitStatus::default())
}
#[cfg(all(feature = "std", windows))]
#[must_use]
pub fn default_success() -> Self {
Self::Windows(windows::ExitCode::default())
}
#[cfg(all(feature = "std", unix))]
#[must_use]
pub fn default_failure() -> Self {
Self::Unix(unix::WaitStatus::from_raw(1)) }
#[cfg(all(feature = "std", windows))]
#[must_use]
pub fn default_failure() -> Self {
Self::Windows(windows::ExitCode::from_raw(1)) }
pub fn ok(&self) -> Result<(), Self> {
if self.is_success() {
Ok(())
} else {
Err(*self)
}
}
#[must_use]
pub fn is_success(&self) -> bool {
match self {
ProcResult::Unix(status) => status.exit_code().is_some_and(|code| code.is_success()),
ProcResult::Windows(code) => code.is_success(),
}
}
#[must_use]
pub fn is_failure(&self) -> bool {
!self.is_success()
}
}
#[cfg(feature = "std")]
impl Display for ProcResult {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Unix(status) => write!(f, "Unix exit status: {}", status.to_raw()),
Self::Windows(code) => write!(f, "Windows exit code: {}", code.to_raw()),
}
}
}
impl core::error::Error for ProcResult {}
#[cfg(all(feature = "std", unix))]
impl From<std::process::ExitStatus> for ProcResult {
#[allow(unreachable_code)]
fn from(status: std::process::ExitStatus) -> Self {
Self::Unix(status.into())
}
}
#[cfg(all(feature = "std", windows))]
impl From<std::process::ExitStatus> for ProcResult {
#[allow(unreachable_code)]
fn from(status: std::process::ExitStatus) -> Self {
Self::Windows(status.into())
}
}
#[cfg(test)]
mod tests {
#[test]
#[cfg(feature = "std")]
fn test_default_success_proc_result() {
use super::ProcResult;
let result = ProcResult::default_success();
assert!(result.is_success());
}
#[test]
#[cfg(feature = "std")]
fn test_default_failure_proc_result() {
use super::ProcResult;
let result = ProcResult::default_failure();
assert!(result.is_failure());
}
}