From 263cb0a5e3cd7dffc8fd72b8492452a05d928734 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Wed, 2 Aug 2023 04:18:16 +0200 Subject: Genesis commit --- .gitignore | 2 + Cargo.toml | 11 ++++++ LICENSE | 14 +++++++ README.md | 6 +++ src/lib.rs | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 src/lib.rs 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 "] +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 `` 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)*); + }; +} -- cgit v1.2.3