1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
#![warn(missing_docs)]
//! Provide a .diag() function for diagnostic output if requested.
//!
//! The [`ConfigDiag`] trait may be used to decorate an object that
//! stores some kind of configuration information. It adds
//! a [`diag`][`ConfigDiag::diag`] method that checks whether
//! verbose output has been requested and,
//! if so, displays a message to the standard error stream.
//! If the [`diag_to_stderr`][`ConfigDiag::diag_to_stderr`] method is
//! overridden and it returns false, any diagnostic messages selected for
//! display are sent to the standard output stream instead.
//!
//! Example:
//!
//! ```rust
//! # use std::error;
//! #
//! use config_diag::ConfigDiag;
//!
//! struct Config {
//! verbose: bool,
//! }
//!
//! impl ConfigDiag for Config {
//! fn diag_is_verbose(&self) -> bool {
//! self.verbose
//! }
//! }
//!
//! # pub fn main() -> Result<(), Box<dyn error::Error>> {
//! let config = Config { verbose: true };
//! # let event = 42;
//! config.diag(|| format!("Something happened: {}", event));
//! config.diag_("Got here!");
//! # Ok(())
//! # }
#![doc(html_root_url = "https://docs.rs/config-diag/1.0.2")]
/*
* Copyright (c) 2021, 2022 Peter Pentchev <roam@ringlet.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/// Provide a `.diag()` function for verbose output if requested.
/// Useful for decorating configuration-like classes.
pub trait ConfigDiag {
/// Has verbose output been requested?
fn diag_is_verbose(&self) -> bool;
/// Should diagnostic messages go to the standard error stream?
/// If overridden to return false, the messages are sent to
/// the standard output stream instead.
#[inline]
fn diag_to_stderr(&self) -> bool {
true
}
/// Output a message to the standard error stream if requested.
/// If the [`Self::diag_is_verbose`] method returns true,
/// call the specified function to build a diagnostic message and
/// write the latter to the stream selected by
/// [`Self::diag_to_stderr`].
#[inline]
#[allow(clippy::print_stderr)]
#[allow(clippy::print_stdout)]
fn diag<F>(&self, f: F)
where
F: FnOnce() -> String,
{
if self.diag_is_verbose() {
let msg = f();
if self.diag_to_stderr() {
eprintln!("{}", msg);
} else {
println!("{}", msg);
}
}
}
/// Output a constant message to the standard error stream if requested.
/// If the [`Self::diag_is_verbose`] method returns true,
/// write the specified message to the stream selected by
/// [`Self::diag_to_stderr`].
#[inline]
fn diag_(&self, msg: &str) {
self.diag(|| msg.to_owned());
}
}
#[cfg(test)]
pub mod tests;