mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
Merge pull request #2586 from Funky185540/docs/document-macros
macros: Add documentation with examples to macros
This commit is contained in:
commit
6c6e047453
1 changed files with 233 additions and 11 deletions
|
@ -1,3 +1,37 @@
|
|||
//! Macros for the uucore utilities.
|
||||
//!
|
||||
//! This module bundles all macros used across the uucore utilities. These
|
||||
//! include macros for reporting errors in various formats, aborting program
|
||||
//! execution and more.
|
||||
//!
|
||||
//! To make use of all macros in this module, they must be imported like so:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! #[macro_use]
|
||||
//! extern crate uucore;
|
||||
//! ```
|
||||
//!
|
||||
//! Alternatively, you can import single macros by importing them through their
|
||||
//! fully qualified name like this:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use uucore::{show, crash};
|
||||
//! ```
|
||||
//!
|
||||
//! Here's an overview of the macros sorted by purpose
|
||||
//!
|
||||
//! - Print errors
|
||||
//! - From types implementing [`crate::error::UError`]: [`show!`],
|
||||
//! [`show_if_err!`]
|
||||
//! - From custom messages: [`show_error!`], [`show_usage_error!`]
|
||||
//! - Print warnings: [`show_warning!`]
|
||||
//! - Terminate util execution
|
||||
//! - Terminate regularly: [`exit!`], [`return_if_err!`]
|
||||
//! - Crash program: [`crash!`], [`crash_if_err!`], [`safe_unwrap!`]
|
||||
//! - Unwrapping result types: [`safe_unwrap!`]
|
||||
|
||||
// spell-checker:ignore sourcepath targetpath
|
||||
|
||||
use std::sync::atomic::AtomicBool;
|
||||
|
||||
// This file is part of the uutils coreutils package.
|
||||
|
@ -12,6 +46,45 @@ pub static UTILITY_IS_SECOND_ARG: AtomicBool = AtomicBool::new(false);
|
|||
|
||||
//====
|
||||
|
||||
/// Display a [`crate::error::UError`] and set global exit code.
|
||||
///
|
||||
/// Prints the error message contained in an [`crate::error::UError`] to stderr
|
||||
/// and sets the exit code through [`crate::error::set_exit_code`]. The printed
|
||||
/// error message is prepended with the calling utility's name. A call to this
|
||||
/// macro will not finish program execution.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// The following example would print a message "Some error occurred" and set
|
||||
/// the utility's exit code to 2.
|
||||
///
|
||||
/// ```
|
||||
/// # #[macro_use]
|
||||
/// # extern crate uucore;
|
||||
///
|
||||
/// use uucore::error::{self, USimpleError};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let err = USimpleError::new(2, "Some error occurred.");
|
||||
/// show!(err);
|
||||
/// assert_eq!(error::get_exit_code(), 2);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If not using [`crate::error::UError`], one may achieve the same behavior
|
||||
/// like this:
|
||||
///
|
||||
/// ```
|
||||
/// # #[macro_use]
|
||||
/// # extern crate uucore;
|
||||
///
|
||||
/// use uucore::error::set_exit_code;
|
||||
///
|
||||
/// fn main() {
|
||||
/// set_exit_code(2);
|
||||
/// show_error!("Some error occurred.");
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! show(
|
||||
($err:expr) => ({
|
||||
|
@ -21,6 +94,36 @@ macro_rules! show(
|
|||
})
|
||||
);
|
||||
|
||||
/// Display an error and set global exit code in error case.
|
||||
///
|
||||
/// Wraps around [`show!`] and takes a [`crate::error::UResult`] instead of a
|
||||
/// [`crate::error::UError`] type. This macro invokes [`show!`] if the
|
||||
/// [`crate::error::UResult`] is an `Err`-variant. This can be invoked directly
|
||||
/// on the result of a function call, like in the `install` utility:
|
||||
///
|
||||
/// ```ignore
|
||||
/// show_if_err!(copy(sourcepath, &targetpath, b));
|
||||
/// ```
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```ignore
|
||||
/// # #[macro_use]
|
||||
/// # extern crate uucore;
|
||||
/// # use uucore::error::{UError, UIoError, UResult, USimpleError};
|
||||
///
|
||||
/// # fn main() {
|
||||
/// let is_ok = Ok(1);
|
||||
/// // This does nothing at all
|
||||
/// show_if_err!(is_ok);
|
||||
///
|
||||
/// let is_err = Err(USimpleError::new(1, "I'm an error").into());
|
||||
/// // Calls `show!` on the contained USimpleError
|
||||
/// show_if_err!(is_err);
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
///
|
||||
#[macro_export]
|
||||
macro_rules! show_if_err(
|
||||
($res:expr) => ({
|
||||
|
@ -31,6 +134,19 @@ macro_rules! show_if_err(
|
|||
);
|
||||
|
||||
/// Show an error to stderr in a similar style to GNU coreutils.
|
||||
///
|
||||
/// Takes a [`format!`]-like input and prints it to stderr. The output is
|
||||
/// prepended with the current utility's name.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #[macro_use]
|
||||
/// # extern crate uucore;
|
||||
/// # fn main() {
|
||||
/// show_error!("Couldn't apply {} to {}", "foo", "bar");
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! show_error(
|
||||
($($args:tt)+) => ({
|
||||
|
@ -40,6 +156,17 @@ macro_rules! show_error(
|
|||
);
|
||||
|
||||
/// Show a warning to stderr in a similar style to GNU coreutils.
|
||||
///
|
||||
/// Is this really required? Used in the following locations:
|
||||
///
|
||||
/// ./src/uu/head/src/head.rs:12
|
||||
/// ./src/uu/head/src/head.rs:424
|
||||
/// ./src/uu/head/src/head.rs:427
|
||||
/// ./src/uu/head/src/head.rs:430
|
||||
/// ./src/uu/head/src/head.rs:453
|
||||
/// ./src/uu/du/src/du.rs:339
|
||||
/// ./src/uu/wc/src/wc.rs:270
|
||||
/// ./src/uu/wc/src/wc.rs:273
|
||||
#[macro_export]
|
||||
macro_rules! show_error_custom_description (
|
||||
($err:expr,$($args:tt)+) => ({
|
||||
|
@ -48,6 +175,21 @@ macro_rules! show_error_custom_description (
|
|||
})
|
||||
);
|
||||
|
||||
/// Print a warning message to stderr.
|
||||
///
|
||||
/// Takes [`format!`]-compatible input and prepends it with the current
|
||||
/// utility's name and "warning: " before printing to stderr.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #[macro_use]
|
||||
/// # extern crate uucore;
|
||||
/// # fn main() {
|
||||
/// // outputs <name>: warning: Couldn't apply foo to bar
|
||||
/// show_warning!("Couldn't apply {} to {}", "foo", "bar");
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! show_warning(
|
||||
($($args:tt)+) => ({
|
||||
|
@ -57,6 +199,21 @@ macro_rules! show_warning(
|
|||
);
|
||||
|
||||
/// Show a bad invocation help message in a similar style to GNU coreutils.
|
||||
///
|
||||
/// Takes a [`format!`]-compatible input and prepends it with the current
|
||||
/// utility's name before printing to stderr.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #[macro_use]
|
||||
/// # extern crate uucore;
|
||||
/// # fn main() {
|
||||
/// // outputs <name>: Couldn't apply foo to bar
|
||||
/// // Try '<name> --help' for more information.
|
||||
/// show_usage_error!("Couldn't apply {} to {}", "foo", "bar");
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! show_usage_error(
|
||||
($($args:tt)+) => ({
|
||||
|
@ -68,7 +225,9 @@ macro_rules! show_usage_error(
|
|||
|
||||
//====
|
||||
|
||||
/// Calls `exit()` with the provided exit code.
|
||||
/// Calls [`std::process::exit`] with the provided exit code.
|
||||
///
|
||||
/// Why not call exit directly?
|
||||
#[macro_export]
|
||||
macro_rules! exit(
|
||||
($exit_code:expr) => ({
|
||||
|
@ -76,7 +235,22 @@ macro_rules! exit(
|
|||
})
|
||||
);
|
||||
|
||||
/// Display the provided error message, then `exit()` with the provided exit code
|
||||
/// Display an error and [`exit!`]
|
||||
///
|
||||
/// Displays the provided error message using [`show_error!`], then invokes
|
||||
/// [`exit!`] with the provided exit code.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```should_panic
|
||||
/// # #[macro_use]
|
||||
/// # extern crate uucore;
|
||||
/// # fn main() {
|
||||
/// // outputs <name>: Couldn't apply foo to bar
|
||||
/// // and terminates execution
|
||||
/// crash!(1, "Couldn't apply {} to {}", "foo", "bar");
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! crash(
|
||||
($exit_code:expr, $($args:tt)+) => ({
|
||||
|
@ -85,8 +259,26 @@ macro_rules! crash(
|
|||
})
|
||||
);
|
||||
|
||||
/// Unwraps the Result. Instead of panicking, it exists the program with the
|
||||
/// provided exit code.
|
||||
/// Unwrap a [`std::result::Result`], crashing instead of panicking.
|
||||
///
|
||||
/// If the result is an `Ok`-variant, returns the value contained inside. If it
|
||||
/// is an `Err`-variant, invokes [`crash!`] with the formatted error instead.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```should_panic
|
||||
/// # #[macro_use]
|
||||
/// # extern crate uucore;
|
||||
/// # fn main() {
|
||||
/// let is_ok: Result<u32, &str> = Ok(1);
|
||||
/// // Does nothing
|
||||
/// crash_if_err!(1, is_ok);
|
||||
///
|
||||
/// let is_err: Result<u32, &str> = Err("This didn't work...");
|
||||
/// // Calls `crash!`
|
||||
/// crash_if_err!(1, is_err);
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! crash_if_err(
|
||||
($exit_code:expr, $exp:expr) => (
|
||||
|
@ -97,18 +289,42 @@ macro_rules! crash_if_err(
|
|||
)
|
||||
);
|
||||
|
||||
//====
|
||||
|
||||
/// Unwrap some Result, crashing instead of panicking.
|
||||
///
|
||||
/// Drop this in favor of `crash_if_err!`
|
||||
#[macro_export]
|
||||
macro_rules! safe_write(
|
||||
($fd:expr, $($args:tt)+) => (
|
||||
match write!($fd, $($args)+) {
|
||||
Ok(_) => {}
|
||||
Err(f) => panic!("{}", f)
|
||||
macro_rules! safe_unwrap(
|
||||
($exp:expr) => (
|
||||
match $exp {
|
||||
Ok(m) => m,
|
||||
Err(f) => $crate::crash!(1, "{}", f.to_string())
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
//====
|
||||
|
||||
/// Unwraps the Result. Instead of panicking, it shows the error and then
|
||||
/// returns from the function with the provided exit code.
|
||||
/// Assumes the current function returns an i32 value.
|
||||
///
|
||||
/// Replace with `crash_if_err`?
|
||||
#[macro_export]
|
||||
macro_rules! return_if_err(
|
||||
($exit_code:expr, $exp:expr) => (
|
||||
match $exp {
|
||||
Ok(m) => m,
|
||||
Err(f) => {
|
||||
$crate::show_error!("{}", f);
|
||||
return $exit_code;
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
//====
|
||||
|
||||
/// This is used exclusively by du...
|
||||
#[macro_export]
|
||||
macro_rules! safe_writeln(
|
||||
($fd:expr, $($args:tt)+) => (
|
||||
|
@ -123,6 +339,7 @@ macro_rules! safe_writeln(
|
|||
|
||||
//-- message templates : (join utility sub-macros)
|
||||
|
||||
// used only by "cut"
|
||||
#[macro_export]
|
||||
macro_rules! snippet_list_join_oxford_comma {
|
||||
($conjunction:expr, $valOne:expr, $valTwo:expr) => (
|
||||
|
@ -133,6 +350,7 @@ macro_rules! snippet_list_join_oxford_comma {
|
|||
);
|
||||
}
|
||||
|
||||
// used only by "cut"
|
||||
#[macro_export]
|
||||
macro_rules! snippet_list_join {
|
||||
($conjunction:expr, $valOne:expr, $valTwo:expr) => (
|
||||
|
@ -167,6 +385,7 @@ macro_rules! msg_invalid_opt_use {
|
|||
};
|
||||
}
|
||||
|
||||
// Only used by "cut"
|
||||
#[macro_export]
|
||||
macro_rules! msg_opt_only_usable_if {
|
||||
($clause:expr, $flag:expr) => {
|
||||
|
@ -181,6 +400,7 @@ macro_rules! msg_opt_only_usable_if {
|
|||
};
|
||||
}
|
||||
|
||||
// Used only by "cut"
|
||||
#[macro_export]
|
||||
macro_rules! msg_opt_invalid_should_be {
|
||||
($expects:expr, $received:expr, $flag:expr) => {
|
||||
|
@ -200,6 +420,7 @@ macro_rules! msg_opt_invalid_should_be {
|
|||
|
||||
// -- message templates : invalid input : input combinations
|
||||
|
||||
// UNUSED!
|
||||
#[macro_export]
|
||||
macro_rules! msg_expects_one_of {
|
||||
($valOne:expr $(, $remaining_values:expr)*) => (
|
||||
|
@ -207,6 +428,7 @@ macro_rules! msg_expects_one_of {
|
|||
);
|
||||
}
|
||||
|
||||
// Used only by "cut"
|
||||
#[macro_export]
|
||||
macro_rules! msg_expects_no_more_than_one_of {
|
||||
($valOne:expr $(, $remaining_values:expr)*) => (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue