use std::{fmt, str::FromStr};
use strum::{EnumIter, IntoEnumIterator};
#[derive(Debug, Clone, Default, PartialEq, PartialOrd, EnumIter, Copy)]
pub enum Level {
ALL,
FINEST,
FINER,
FINE,
CONFIG,
#[default]
INFO,
WARNING,
SEVERE,
OFF,
}
impl Level {
pub const fn as_str(&self) -> &'static str {
match self {
Level::ALL => "ALL",
Level::FINEST => "FINEST",
Level::FINER => "FINER",
Level::FINE => "FINE",
Level::CONFIG => "CONFIG",
Level::INFO => "INFO",
Level::WARNING => "WARNING",
Level::SEVERE => "SEVERE",
Level::OFF => "OFF",
}
}
}
impl fmt::Display for Level {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.as_str().fmt(f)
}
}
#[allow(dead_code)]
#[derive(Debug)]
pub struct LevelError {
msg: String,
}
impl FromStr for Level {
type Err = LevelError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ALL" => Ok(Level::ALL),
"FINEST" => Ok(Level::FINEST),
"FINER" => Ok(Level::FINER),
"FINE" => Ok(Level::FINE),
"CONFIG" => Ok(Level::CONFIG),
"INFO" => Ok(Level::INFO),
"WARNING" => Ok(Level::WARNING),
"SEVERE" => Ok(Level::SEVERE),
"OFF" => Ok(Level::OFF),
_ => Err(LevelError {
msg: format!("Unknown Level: {s}"),
}),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn compare_levels() {
let log_level = Level::default();
let b = Level::FINE;
println!("\n|{log_level}|\n");
assert!(b < log_level);
}
#[test]
fn check_conversions() {
for level in Level::iter() {
let lstr = level.as_str();
let l = Level::from_str(lstr).unwrap();
assert_eq!(level, l);
}
assert!(Level::from_str("DEBUG").is_err());
}
}