diff options
| author | Thomas Voss <mail@thomasvoss.com> | 2023-08-03 17:52:43 +0200 | 
|---|---|---|
| committer | Thomas Voss <mail@thomasvoss.com> | 2023-08-03 17:55:51 +0200 | 
| commit | 1e05dc096d7c24087c720ae61d2c6fb296e50286 (patch) | |
| tree | 1c8ad6f908fd64114554ab77b4a51fb8c51423e0 | |
| parent | 97f5ace71262a74f89a0e6e31ec7b849d81af147 (diff) | |
Introduce the require!() macrov1.1.0
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/lib.rs | 63 | 
2 files changed, 64 insertions, 1 deletions
| @@ -1,6 +1,6 @@  [package]  name = "cerm" -version = "1.0.0" +version = "1.1.0"  edition = "2021"  authors = ["Thomas Voss <mail@thomasvoss.com>"]  description = "C-inspired error reporting macros" @@ -122,3 +122,66 @@ macro_rules! warn {  		eprintln!($($fmt)+);  	};  } + +/// Require that an expression returns [`Result::Ok`] or [`Option::Some`]. +/// +/// This macro simplifies error handling when the [`Result::Err`] or +/// [`Option::None`] cases of a [`std::result::Result`] or an +/// [`std::option::Option`] result in logging an error and terminating the +/// program. +/// +/// When invoked with a [`std::result::Result`], the macro takes only 1 parameter +/// — the [`std::result::Result`] whose success case you require — and in the +/// case of `Err(v)` returns `v`.  Otherwise the [`err!`] macro is called with +/// the format string `"{e}"` (with `e` being the error). +/// +/// Since [`std::option::Option`]s don’t return error values — simply returning +/// [`Option::None` ]— we can’t print a meaningful diagnostic message for you. +/// Therefore you the user also need to provide as additional arguments the same +/// parameters you would pass to an invokation of [`err!`]. +/// +/// # Panics +/// +/// Calls [`err!`] which may panic if it fails. +/// +/// # Examples +/// +/// Try to take a child process’ standard input and assign it to `ci`.  If the +/// result of `stdin.take()` is [`Option::None` ]then print the given diagnostic +/// message and exit the program using [`err!`]. +/// +/// ``` +/// use cerm::require; +/// +/// let ci = require!( +/// 	child.stdin.take(), +/// 	"Failed to open stdin of “{}”", +/// 	cmd.to_string_lossy() +/// ); +/// ``` +/// +/// +/// Wait for a child process to terminate, and execute [`err!`] if the call to +/// `child.wait()` fails.  Notice how because `child.wait()` returns a +/// [`std::result::Result`], we only specify one argument. +/// +/// ``` +/// use cerm::require; +/// +/// require!(child.wait()); +/// ``` +#[macro_export] +macro_rules! require { +	($e:expr) => { +		match $e { +			Ok(v) => v, +			Err(e) => { err!("{e}"); }, +		} +	}; +	($e:expr, $($fmt:tt)+) => { +		match $e { +			Some(v) => v, +			None => { err!($($fmt)+); }, +		} +	}; +} |