use std::{error, fmt};
#[derive(Clone, Debug)]
pub struct ExitError {
pub code: u8,
pub message: Option<String>,
}
impl ExitError {
pub fn new(code: u8, message: Option<String>) -> Self {
Self { code, message }
}
pub fn new_from<ToStringT>(code: u8, to_string: ToStringT) -> Self
where
ToStringT: ToString,
{
Self::new(code, Some(to_string.to_string()))
}
pub fn success() -> Self {
0.into()
}
}
impl error::Error for ExitError {}
impl fmt::Display for ExitError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.message {
Some(message) => write!(formatter, "exit code {}: {}", self.code, message),
None => Ok(()),
}
}
}
impl From<u8> for ExitError {
fn from(value: u8) -> Self {
Self::new(value, None)
}
}
impl From<String> for ExitError {
fn from(message: String) -> Self {
Self::new(1, Some(message))
}
}
impl From<&str> for ExitError {
fn from(message: &str) -> Self {
message.to_string().into()
}
}
#[macro_export]
macro_rules! handle_exit_error {
( $error_enum:ty, $exit_error_variant:ident $(,)? ) => {
impl $crate::cli::run::RunError for $error_enum {
fn handle(&self) -> (bool, u8) {
(
false,
match self {
Self::$exit_error_variant(exit_error) => exit_error.code,
_ => 1,
},
)
}
}
};
}
#[allow(unused_imports)]
pub use handle_exit_error;