#[cfg(not(feature = "test"))]
use std::process;
pub const DEFAULT_EXIT_CODE: i32 = 1;
#[cfg(feature = "red")]
macro_rules! eprintln {
($($arg:tt)*) => {
use std::io::Write;
writeln!(&mut ::std::io::stderr(), "\u{001b}[91;49;1m{}\u{001b}[0m", format!($($arg)*)).expect("failed printing to stderr");
};
}
#[cfg(not(feature = "test"))]
#[macro_export]
macro_rules! die {
() => (::std::process::exit(::die_exit::DEFAULT_EXIT_CODE));
($x:expr) => (::die_exit::PrintExit::print_exit(&$x));
($x:expr; $y:expr) => (::die_exit::PrintExit::print_exit(&($x, $y)));
($x:expr; $($y:expr),+) => ({
eprintln!($($y),+);
::std::process::exit($x)
});
($($y:expr),+; $x:expr) => ({
eprintln!($($y),+);
::std::process::exit($x)
});
($($arg:tt)*) => ({
eprintln!($($arg)*);
::std::process::exit(::die_exit::DEFAULT_EXIT_CODE)
});
}
#[cfg(feature = "test")]
#[macro_export]
macro_rules! die {
() => (
panic!("Exited with code {}", ::die_exit::DEFAULT_EXIT_CODE)
);
($x:expr) => (::die_exit::PrintExit::print_exit(&$x));
($x:expr; $y:expr) => (::die_exit::PrintExit::print_exit(&($x, $y)));
($x:expr; $($y:expr),+) => ({
eprintln!($($y),+);
panic!("Exited with code {}", $x)
});
($($y:expr),+; $x:expr) => ({
eprintln!($($y),+);
panic!("Exited with code {}", $x)
});
($($arg:tt)*) => ({
eprintln!($($arg)*);
panic!("Exited with code {}", ::die_exit::DEFAULT_EXIT_CODE)
});
}
pub trait Die<T> {
fn die(self, msg: &str) -> T;
fn die_code(self, msg: &str, exit_code: i32) -> T;
}
pub trait DieWith<T, E> {
fn die_with<X: PrintExit, F: FnOnce(E) -> X>(self, func: F) -> T;
}
impl<T, E> Die<T> for Result<T, E> {
#[inline]
fn die(self, msg: &str) -> T {
self.die_code(msg, DEFAULT_EXIT_CODE)
}
#[inline]
fn die_code(self, msg: &str, exit_code: i32) -> T {
match self {
Ok(t) => t,
Err(_) => PrintExit::print_exit(&(exit_code, msg)),
}
}
}
impl<T> Die<T> for Option<T> {
#[inline]
fn die(self, msg: &str) -> T {
self.die_code(msg, DEFAULT_EXIT_CODE)
}
#[inline]
fn die_code(self, msg: &str, exit_code: i32) -> T {
match self {
Some(t) => t,
None => PrintExit::print_exit(&(exit_code, msg)),
}
}
}
impl<T, E> DieWith<T, E> for Result<T, E> {
#[inline]
fn die_with<X: PrintExit, F: FnOnce(E) -> X>(self, func: F) -> T {
match self {
Ok(t) => t,
Err(err) => PrintExit::print_exit(&func(err)),
}
}
}
pub trait PrintExit {
fn print_exit(&self) -> !;
}
impl PrintExit for i32 {
#[inline]
fn print_exit(&self) -> ! {
#[cfg(feature = "test")]
panic!("Exited with code {}", *self);
#[cfg(not(feature = "test"))]
process::exit(*self)
}
}
impl PrintExit for &str {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self);
#[cfg(feature = "test")]
panic!("Exited with code {}", DEFAULT_EXIT_CODE);
#[cfg(not(feature = "test"))]
process::exit(DEFAULT_EXIT_CODE)
}
}
impl PrintExit for String {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self);
#[cfg(feature = "test")]
panic!("Exited with code {}", DEFAULT_EXIT_CODE);
#[cfg(not(feature = "test"))]
process::exit(DEFAULT_EXIT_CODE)
}
}
impl PrintExit for (i32, &str) {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self.1);
#[cfg(feature = "test")]
panic!("Exited with code {}", self.0);
#[cfg(not(feature = "test"))]
process::exit(self.0)
}
}
impl PrintExit for (i32, String) {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self.1);
#[cfg(feature = "test")]
panic!("Exited with code {}", self.0);
#[cfg(not(feature = "test"))]
process::exit(self.0)
}
}
impl PrintExit for (&str, i32) {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self.0);
#[cfg(feature = "test")]
panic!("Exited with code {}", self.1);
#[cfg(not(feature = "test"))]
process::exit(self.1)
}
}
impl PrintExit for (String, i32) {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self.0);
#[cfg(feature = "test")]
panic!("Exited with code {}", self.1);
#[cfg(not(feature = "test"))]
process::exit(self.1)
}
}