use clap::Parser;
use libpt_log::Level;
#[cfg(feature = "log")]
use log;
use serde::{Deserialize, Serialize};
pub const HELP_TEMPLATE: &str = r"{about-section}
{usage-heading} {usage}
{all-args}{tab}
{name}: {version}
Author: {author-with-newline}
";
#[derive(Parser, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct VerbosityLevel {
#[arg(
long,
short = 'v',
action = clap::ArgAction::Count, // NOTE: this forces u8 type for some reason
global = true,
// help = L::verbose_help(),
// long_help = L::verbose_long_help(),
)]
verbose: u8,
#[arg(
long,
short = 'q',
action = clap::ArgAction::Count,
global = true,
conflicts_with = "verbose",
)]
quiet: u8,
}
impl VerbosityLevel {
#[inline]
#[must_use]
#[allow(clippy::missing_const_for_fn)] pub fn changed(&self) -> bool {
self.verbose != 0 || self.quiet != 0
}
#[inline]
#[must_use]
fn value(&self) -> u8 {
Self::level_value(Level::INFO)
.saturating_sub((self.quiet).min(10))
.saturating_add((self.verbose).min(10))
}
#[inline]
#[must_use]
pub fn level(&self) -> Level {
let v = self.value();
match v {
0 => Level::ERROR,
1 => Level::WARN,
2 => Level::INFO,
3 => Level::DEBUG,
4 => Level::TRACE,
_ => {
if v > 4 {
Level::TRACE
} else {
Level::ERROR
}
}
}
}
#[inline]
#[must_use]
#[cfg(feature = "log")]
pub fn level_for_log_crate(&self) -> log::Level {
match self.level() {
Level::TRACE => log::Level::Trace,
Level::DEBUG => log::Level::Debug,
Level::INFO => log::Level::Info,
Level::WARN => log::Level::Warn,
Level::ERROR => log::Level::Error,
}
}
#[inline]
#[must_use]
const fn level_value(level: Level) -> u8 {
match level {
Level::TRACE => 4,
Level::DEBUG => 3,
Level::INFO => 2,
Level::WARN => 1,
Level::ERROR => 0,
}
}
pub const TRACE: Self = Self {
verbose: 2,
quiet: 0,
};
pub const DEBUG: Self = Self {
verbose: 1,
quiet: 0,
};
pub const INFO: Self = Self {
verbose: 0,
quiet: 0,
};
pub const WARN: Self = Self {
verbose: 0,
quiet: 1,
};
pub const ERROR: Self = Self {
verbose: 0,
quiet: 2,
};
}
impl std::fmt::Debug for VerbosityLevel {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.level())
}
}
impl Default for VerbosityLevel {
fn default() -> Self {
Self::INFO
}
}