use std::process;
pub const DEFAULT_EXIT_CODE: i32 = 1;
#[macro_export]
macro_rules! die {
() => (::std::process::exit(::die::DEFAULT_EXIT_CODE));
($x:expr) => (::die::PrintExit::print_exit(&$x));
($x:expr; $y:expr) => (::die::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::DEFAULT_EXIT_CODE)
});
}
pub trait Die<T> {
fn die(self, msg: &str) -> T;
fn die_code(self, msg: &str, exit_code: i32) -> 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)),
}
}
}
pub trait PrintExit {
#[inline]
fn print_exit(&self) -> !;
}
impl PrintExit for i32 {
#[inline]
fn print_exit(&self) -> ! {
process::exit(*self)
}
}
impl PrintExit for &str {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self);
process::exit(DEFAULT_EXIT_CODE)
}
}
impl PrintExit for String {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self);
process::exit(DEFAULT_EXIT_CODE)
}
}
impl PrintExit for (i32, &str) {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self.1);
process::exit(self.0)
}
}
impl PrintExit for (i32, String) {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self.1);
process::exit(self.0)
}
}
impl PrintExit for (&str, i32) {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self.0);
process::exit(self.1)
}
}
impl PrintExit for (String, i32) {
#[inline]
fn print_exit(&self) -> ! {
eprintln!("{}", self.0);
process::exit(self.1)
}
}