use super::TracingError;
use std::fmt;
use std::str::FromStr;
use tracing::Level;
#[derive(Clone, Copy, Debug, Default)]
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
pub enum LogLevel {
Off,
Error,
Warn,
#[default]
Info,
Debug,
Trace,
Verbose,
}
impl LogLevel {
pub fn is_off(&self) -> bool {
matches!(self, Self::Off)
}
pub fn is_verbose(&self) -> bool {
matches!(self, Self::Verbose)
}
pub fn to_tracing_level(&self) -> Option<Level> {
match self {
Self::Off => None,
Self::Error => Some(Level::ERROR),
Self::Warn => Some(Level::WARN),
Self::Info => Some(Level::INFO),
Self::Debug => Some(Level::DEBUG),
Self::Trace | Self::Verbose => Some(Level::TRACE),
}
}
}
impl fmt::Display for LogLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(
f,
"{}",
match self {
Self::Off => "off",
Self::Error => "error",
Self::Warn => "warn",
Self::Info => "info",
Self::Debug => "debug",
Self::Trace => "trace",
Self::Verbose => "verbose",
}
)
}
}
impl TryFrom<String> for LogLevel {
type Error = TracingError;
fn try_from(value: String) -> Result<Self, TracingError> {
Self::from_str(value.as_str())
}
}
impl TryFrom<&str> for LogLevel {
type Error = TracingError;
fn try_from(value: &str) -> Result<Self, TracingError> {
Self::from_str(value)
}
}
impl FromStr for LogLevel {
type Err = TracingError;
fn from_str(value: &str) -> Result<Self, Self::Err> {
Ok(match value.to_lowercase().as_str() {
"off" => Self::Off,
"error" => Self::Error,
"warn" => Self::Warn,
"info" => Self::Info,
"debug" => Self::Debug,
"trace" => Self::Trace,
"verbose" => Self::Verbose,
other => {
return Err(TracingError::LogLevelInvalid {
level: other.to_string(),
});
}
})
}
}