aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2023-08-02 04:18:16 +0200
committerThomas Voss <mail@thomasvoss.com> 2023-08-02 04:26:09 +0200
commit263cb0a5e3cd7dffc8fd72b8492452a05d928734 (patch)
treefc12affd3ee294453febb973e4694aac0283ea82
Genesis commitv1.0.0
-rw-r--r--.gitignore2
-rw-r--r--Cargo.toml11
-rw-r--r--LICENSE14
-rw-r--r--README.md6
-rw-r--r--src/lib.rs124
5 files changed, 157 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4fffb2f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/target
+/Cargo.lock
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..114b6d8
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "cerm"
+version = "1.0.0"
+edition = "2021"
+authors = ["Thomas Voss <mail@thomasvoss.com>"]
+description = "C-inspired error reporting macros"
+readme = "README.md"
+repository = "https://git.thomasvoss.com/cerm"
+license = "0BSD"
+keywords = ["exit", "terminate", "error", "error-message"]
+categories = ["command-line-interface"]
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..276994d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,14 @@
+BSD Zero Clause License
+
+Copyright © 2023 Thomas Voss
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c014ec2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+# `cerm` — C Inspired Error Reporting Macros
+
+This crate provides a few handy macros in the style of BSD C’s `<err.h>` for
+error-reporting to the user. These macros just remove some of the boilerplate of
+having to prefix your diagnostic messages with `progname: ` everytime you want to
+exit the program.
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..685c023
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,124 @@
+#![doc = include_str!("../README.md")]
+
+#[doc(hidden)]
+pub use std::{env, process};
+
+/// Print a diagnostic message to stderr and exit with a given code.
+///
+/// This macro is analagous to the BSD [`errx(3)`] C function. It takes at a
+/// minimum two arguments. The first argument is the code with passed to
+/// [`std::process::exit()`] with which we exit the program. The second and
+/// optional additional arguments are passed to the [`eprintln!`] macro.
+///
+/// When invoked, the given format and arguments are printed to the standard
+/// error, prepended by the string `"progname: "`, where `progname` is the
+/// program name as defined by the first element in [`std::env::args`]. If for
+/// whatever reason no such element exists (which is possible), we default to
+/// simply using `"Error"` as the program name.
+///
+/// If you do not care about specifying a specific exit code and are fine with
+/// simply defaulting to `1`, you may prefer to use [`err!`].
+///
+/// # Panics
+///
+/// Calls [`eprint!`], [`eprintln!`], and [`std::env::args`] which may all panic
+/// if they fail.
+///
+/// # Examples
+///
+/// Print a diagnostic in the form `progname: path: error`, and then exit the
+/// program with an exit status of 2.
+///
+/// ```
+/// use std::fs;
+/// use cerm::err_code;
+///
+/// let res = match fs::create_dir(&path) {
+/// Ok(v) => v,
+/// Err(e) => { err_code!(2, "{}: {}", path, e); }
+/// };
+/// ```
+///
+/// [`errx(3)`]: https://man.openbsd.org/err.3
+#[macro_export]
+macro_rules! err_code {
+ ($code:tt, $($fmt:tt)+) => {
+ eprint!("{}: ", $crate::env::args().next().unwrap_or("Error".into()));
+ eprintln!($($fmt)*);
+ $crate::process::exit($code);
+ };
+}
+
+/// The same thing as [`err_code!`], but the exit code is always 1.
+///
+/// This macro is simply a wrapper around [`err_code!`], but with `1` passed as
+/// the first argument; everything else is the same. For documentation on this
+/// macro, read the documentation for [`err_code!`] instead.
+///
+/// # Panics
+///
+/// Calls [`err!`] which may panic if it fails.
+///
+/// # Examples
+///
+/// Print a diagnostic in the form `progname: path: error`, and then exit the
+/// program with an exit status of 1.
+///
+/// ```
+/// use std::fs;
+/// use cerm::err_code;
+///
+/// let res = match fs::create_dir(&path) {
+/// Ok(v) => v,
+/// Err(e) => { err!("{}: {}", path, e); }
+/// };
+/// ```
+#[macro_export]
+macro_rules! err {
+ ($($fmt:tt)+) => {
+ $crate::err_code!(1, $($fmt)*);
+ }
+}
+
+/// Print a diagnostic message to stderr
+///
+/// This macro is analagous to the BSD [`warnx(3)`] C function. It takes the
+/// same arguments one would pass to a macro like [`println!`]. In fact, the
+/// arguments are passed directly to [`eprintln]`.
+///
+/// When invoked, the given format and arguments are printed to the standard
+/// error, prepended by the string `"progname: "`, where `progname` is the
+/// program name as defined by the first element in [`std::env::args`]. If for
+/// whatever reason no such element exists (which is possible), we default to
+/// simply using `"Error"` as the program name.
+///
+/// # Panics
+///
+/// Calls [`eprint!`], [`eprintln!`], and [`std::env::args`] which may all panic
+/// if they fail.
+///
+/// # Examples
+///
+/// Print a diagnostic in the form `progname: path: error`
+///
+/// ```
+/// use std::fs;
+/// use cerm::warn;
+///
+/// let res = match fs::create_dir(&path) {
+/// Ok(v) => v,
+/// Err(e) => {
+/// warn!("{}: {}", path, e);
+/// /* … */
+/// }
+/// };
+/// ```
+///
+/// [`errx(3)`]: https://man.openbsd.org/err.3
+#[macro_export]
+macro_rules! warn {
+ ($($fmt:tt)+) => {
+ eprint!("{}: ", $crate::env::args().next().unwrap_or("Error".into()));
+ eprintln!($($fmt)*);
+ };
+}