#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Code(i32);
impl Code {
pub const SUCCESS: Code = Code(0);
pub const FAILURE: Code = Code(1);
pub const fn new(code: i32) -> Self {
Self(code)
}
#[inline]
pub fn from_status(status: std::process::ExitStatus) -> Self {
Self::from(status)
}
}
impl Code {
#[inline]
pub fn process_exit(self) -> ! {
std::process::exit(self.as_raw())
}
#[inline]
pub fn ok(self) -> crate::ExitResult {
if self.as_raw() == Self::SUCCESS.as_raw() {
Ok(())
} else {
Err(crate::Exit::new(self))
}
}
#[inline]
pub fn as_exit(self) -> crate::Exit {
crate::Exit::new(self)
}
#[inline]
pub fn with_message<D: std::fmt::Display + 'static>(self, msg: D) -> crate::Exit {
self.as_exit().with_message(msg)
}
}
impl Code {
#[inline]
pub fn as_exit_code(self) -> Option<std::process::ExitCode> {
self.as_portable().map(|c| c.into())
}
#[inline]
pub const fn as_raw(self) -> i32 {
self.0
}
#[inline]
pub const fn as_portable(self) -> Option<u8> {
if self.is_portable() {
Some(self.as_raw() as u8)
} else {
None
}
}
#[inline]
pub const fn is_ok(self) -> bool {
self.as_raw() == Self::SUCCESS.as_raw()
}
#[inline]
pub const fn is_err(self) -> bool {
!self.is_ok()
}
#[inline]
pub const fn is_portable(self) -> bool {
0 <= self.as_raw() && self.as_raw() <= 255
}
}
impl Default for Code {
#[inline]
fn default() -> Self {
Self::FAILURE
}
}
impl From<i32> for Code {
#[inline]
fn from(n: i32) -> Self {
Self(n)
}
}
impl From<std::process::ExitStatus> for Code {
#[inline]
fn from(status: std::process::ExitStatus) -> Self {
let n = platform_exit_code(status).unwrap_or(Code::default().0);
From::from(n)
}
}
#[cfg(target_family = "unix")]
#[inline]
fn platform_exit_code(status: std::process::ExitStatus) -> Option<i32> {
use std::os::unix::process::ExitStatusExt;
status.code().or_else(|| status.signal())
}
#[cfg(not(target_family = "unix"))]
#[inline]
fn platform_exit_code(status: std::process::ExitStatus) -> Option<i32> {
status.code()
}
impl std::process::Termination for Code {
#[inline]
fn report(self) -> std::process::ExitCode {
self.as_exit_code()
.unwrap_or(std::process::ExitCode::FAILURE)
}
}