Version 0.2.0

This commit is contained in:
Travis Burtrum 2019-02-22 00:55:11 -05:00
parent 732a515996
commit 5b79867caa
5 changed files with 95 additions and 43 deletions

View File

@ -7,4 +7,3 @@ matrix:
script:
- cargo test
- rustdoc --test README.md -L target

2
Cargo.lock generated
View File

@ -2,5 +2,5 @@
# It is not intended for manual editing.
[[package]]
name = "die"
version = "0.1.0"
version = "0.2.0"

View File

@ -1,6 +1,6 @@
[package]
name = "die"
version = "0.1.0"
version = "0.2.0"
authors = ["moparisthebest <admin@moparisthebest.com>"]
description = "Handle errors and exit in command line programs easily."

View File

@ -11,7 +11,33 @@
```toml
# Cargo.toml
[dependencies]
die = "0.1"
die = "0.2"
```
Example usage:
```rust
use die::Die;
// Result:
Ok(1).die("no number"); // unwraps to 1 successfully
Err("failure").die("strange error"); // prints `strange error` to stderr then exits with code 1
// Option:
Some(1).die("no number"); // unwraps to 1 successfully
None.die("none option"); // prints `none option` to stderr then exits with code 1
// custom error codes:
Err("failure").die_code("strange error", 4); // prints `strange error` to stderr then exits with code 4
None.die_code("none option", 5); // prints `none option` to stderr then exits with code 5
// die! macro:
die!("argument to -e must be numeric"); // prints message to stderr then exits with code 1
die!(2; "argument to -e must be numeric"); // prints message to stderr then exits with code 2
die!("argument to -e must be numeric"; 3); // prints message to stderr then exits with code 3
die!("argument {} must be {}", "-e", 1; 4); // prints `argument -e must be 1` to stderr then exits with code 4
die!("argument {} must be {}", "-e", 1); // prints `argument -e must be 1` to stderr then exits with code 1
die!(2); // prints nothing, only exits with code 3
die!(); // prints nothing, only exits with code 1
```
# License

View File

@ -6,55 +6,60 @@
use std::process;
/// const of 1
pub const DEFAULT_EXIT_CODE: i32 = 1;
/// Prints a message to stderr and terminates the current process with the specified exit code
/// or 1 if no exit code is specified, by calling eprintln!() on all arguments followed by
/// process::exit(exit_code)
/// Prints a message to [`stderr`] and terminates the current process with the specified exit code
/// or 1 if no exit code is specified, by calling [`eprintln`]!() on all arguments followed by
/// [process::exit(exit_code)][exit]
///
/// [`eprintln`]: https://doc.rust-lang.org/std/macro.eprintln.html
/// [`stderr`]: https://doc.rust-lang.org/std/io/fn.stderr.html
/// [exit]: https://doc.rust-lang.org/std/process/fn.exit.html
///
/// # Examples
///
/// Basic usage:
///
/// ```{.should_panic}
/// use die::die;
/// # use die::die;
/// die!("argument to -e must be numeric"); // prints message to stderr then exits with code 1
/// ```
/// With custom error code:
/// ```{.should_panic}
/// use die::die;
/// # use die::die;
/// die!(2; "argument to -e must be numeric"); // prints message to stderr then exits with code 2
/// ```
/// error code can go at the beginning or end, just separate with colon:
/// ```{.should_panic}
/// use die::die;
/// # use die::die;
/// die!("argument to -e must be numeric"; 3); // prints message to stderr then exits with code 3
/// ```
/// supports all the formatting eprintln! does:
/// ```{.should_panic}
/// use die::die;
/// # use die::die;
/// die!("argument {} must be {}", "-e", 1; 4); // prints `argument -e must be 1` to stderr then exits with code 4
/// ```
/// supports all the formatting eprintln! does without exit code too:
/// ```{.should_panic}
/// use die::die;
/// # use die::die;
/// die!("argument {} must be {}", "-e", 1); // prints `argument -e must be 1` to stderr then exits with code 1
/// ```
/// just exit with a code alone:
/// ```{.should_panic}
/// use die::die;
/// # use die::die;
/// die!(2); // prints nothing, only exits with code 3
/// ```
/// just exit:
/// ```{.should_panic}
/// use die::die;
/// # use die::die;
/// die!(); // prints nothing, only exits with code 1
/// ```
#[macro_export]
macro_rules! die {
() => (::std::process::exit(::die::DEFAULT_EXIT_CODE));
($x:expr) => (::die::PrintExit::process(&$x));
($x:expr; $y:expr) => (::die::PrintExit::process(&($x, $y)));
($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)
@ -69,50 +74,72 @@ macro_rules! die {
});
}
/// `Die` is a trait implemented on [`Result`] and [`Option`] to make exiting with messages and codes easy
///
/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
/// [`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html
pub trait Die<T> {
/// Unwraps a result/option, yielding the content of an [`Ok`] or [`Some`].
/// Unwraps a [`Result`] or [`Option`], yielding the content of an [`Ok`] or [`Some`].
///
/// # Exits
///
/// Calls process::exit(1) if the value is an [`Err`]/[`None`], after printing the
/// passed message to stderr.
/// Calls [process::exit(1)][exit] if the value is an [`Err`] or [`None`], after printing the
/// passed message to [`stderr`].
///
/// [`Ok`]: enum.Result.html#variant.Ok
/// [`Err`]: enum.Result.html#variant.Err
/// [`Some`]: enum.Option.html#variant.Some
/// [`None`]: enum.Option.html#variant.None
/// [`stderr`]: https://doc.rust-lang.org/std/io/fn.stderr.html
/// [exit]: https://doc.rust-lang.org/std/process/fn.exit.html
/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
/// [`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html
/// [`Ok`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Ok
/// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
/// [`Some`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some
/// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
///
/// # Examples
///
/// Basic usage:
///
/// ```{.should_panic}
/// use die::Die;
/// # use die::Die;
/// let x: Result<u32, &str> = Err("emergency failure");
/// x.die("strange error"); // prints `strange error` to stderr then exits with code 1
/// ```
/// ```{.should_panic}
/// # use die::Die;
/// let x: Option<u32> = None;
/// x.die("strange error"); // prints `strange error` to stderr then exits with code 1
/// ```
fn die(self, msg: &str) -> T;
/// Unwraps a result/option, yielding the content of an [`Ok`] or [`Some`].
/// Unwraps a [`Result`] or [`Option`], yielding the content of an [`Ok`] or [`Some`].
///
/// # Exits
///
/// Calls process::exit(exit_code) if the value is an [`Err`]/[`None`], after printing the
/// passed message to stderr.
/// Calls [process::exit(exit_code)][exit] if the value is an [`Err`] or [`None`], after printing the
/// passed message to [`stderr`].
///
/// [`Ok`]: enum.Result.html#variant.Ok
/// [`Err`]: enum.Result.html#variant.Err
/// [`Some`]: enum.Option.html#variant.Some
/// [`None`]: enum.Option.html#variant.None
/// [`stderr`]: https://doc.rust-lang.org/std/io/fn.stderr.html
/// [exit]: https://doc.rust-lang.org/std/process/fn.exit.html
/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
/// [`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html
/// [`Ok`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Ok
/// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
/// [`Some`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some
/// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
///
/// # Examples
///
/// Basic usage:
///
/// ```{.should_panic}
/// use die::Die;
/// # use die::Die;
/// let x: Result<u32, &str> = Err("emergency failure");
/// x.die_code("strange error", 3); // prints `strange error` to stderr then exits with code 3
/// x.die_code("strange", 3); // prints `strange` to stderr then exits with code 3
/// ```
/// ```{.should_panic}
/// # use die::Die;
/// let x: Option<u32> = None;
/// x.die_code("strange", 3); // prints `strange` to stderr then exits with code 3
/// ```
fn die_code(self, msg: &str, exit_code: i32) -> T;
}
@ -126,7 +153,7 @@ impl<T, E> Die<T> for Result<T, E> {
fn die_code(self, msg: &str, exit_code: i32) -> T {
match self {
Ok(t) => t,
Err(_) => PrintExit::process(&(exit_code, msg)),
Err(_) => PrintExit::print_exit(&(exit_code, msg)),
}
}
}
@ -140,26 +167,26 @@ impl<T> Die<T> for Option<T> {
fn die_code(self, msg: &str, exit_code: i32) -> T {
match self {
Some(t) => t,
None => PrintExit::process(&(exit_code, msg)),
None => PrintExit::print_exit(&(exit_code, msg)),
}
}
}
pub trait PrintExit {
#[inline]
fn process(&self) -> !;
fn print_exit(&self) -> !;
}
impl PrintExit for i32 {
#[inline]
fn process(&self) -> ! {
fn print_exit(&self) -> ! {
process::exit(*self)
}
}
impl PrintExit for &str {
#[inline]
fn process(&self) -> ! {
fn print_exit(&self) -> ! {
eprintln!("{}", self);
process::exit(DEFAULT_EXIT_CODE)
}
@ -167,7 +194,7 @@ impl PrintExit for &str {
impl PrintExit for String {
#[inline]
fn process(&self) -> ! {
fn print_exit(&self) -> ! {
eprintln!("{}", self);
process::exit(DEFAULT_EXIT_CODE)
}
@ -175,7 +202,7 @@ impl PrintExit for String {
impl PrintExit for (i32, &str) {
#[inline]
fn process(&self) -> ! {
fn print_exit(&self) -> ! {
eprintln!("{}", self.1);
process::exit(self.0)
}
@ -183,7 +210,7 @@ impl PrintExit for (i32, &str) {
impl PrintExit for (i32, String) {
#[inline]
fn process(&self) -> ! {
fn print_exit(&self) -> ! {
eprintln!("{}", self.1);
process::exit(self.0)
}
@ -191,7 +218,7 @@ impl PrintExit for (i32, String) {
impl PrintExit for (&str, i32) {
#[inline]
fn process(&self) -> ! {
fn print_exit(&self) -> ! {
eprintln!("{}", self.0);
process::exit(self.1)
}
@ -199,7 +226,7 @@ impl PrintExit for (&str, i32) {
impl PrintExit for (String, i32) {
#[inline]
fn process(&self) -> ! {
fn print_exit(&self) -> ! {
eprintln!("{}", self.0);
process::exit(self.1)
}