use strum_macros::Display;
use strum::IntoEnumIterator;
use strum_macros::EnumIter;
#[cfg(doctest)]
use hclog_macros::HCLog;
use crate::ErrorKind;
#[derive(Copy, Clone, Debug, Default, Display, EnumIter, Hash, Eq, PartialEq, Ord, PartialOrd)]
#[strum(serialize_all = "lowercase")]
pub enum Level {
#[default]
Off = 0,
Emerg,
Alert,
Crit,
Error,
Warn,
Notice,
Info,
Debug1,
Debug2,
Debug3,
Debug4,
Debug5,
Debug6,
Debug7,
Debug8,
Debug9,
Debug10,
}
impl std::str::FromStr for Level {
type Err = ErrorKind;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match Level::iter().find(|r| r.to_string().eq_ignore_ascii_case(s)) {
Some(l) => Ok(l),
None => Err(ErrorKind::UnknownLogLevel),
}
}
}
#[doc(hidden)]
impl Level {
#[inline(always)]
pub fn max() -> Self {
Self::Debug10
}
#[inline(always)]
pub fn min() -> Self {
Self::Off
}
#[inline(always)]
pub fn is_enabled(&self, other: Self) -> bool {
other <= *self
}
pub fn debug_level(id: u8) -> Self {
if id == 0 {
Self::Off
} else {
Level::iter().nth(Self::Info as usize + id as usize).unwrap_or(Self::Debug10)
}
}
}
#[cfg(test)]
mod level_tests {
use crate::level::Level;
use crate::ErrorKind::UnknownLogLevel;
use strum::IntoEnumIterator;
#[test]
fn test_level_from_str() {
assert_eq!("".parse::<Level>(), Err(UnknownLogLevel));
assert_eq!("none".parse::<Level>(), Err(UnknownLogLevel));
assert_eq!("Emerg".parse::<Level>(), Ok(Level::Emerg));
assert_eq!("aLeRT".parse::<Level>(), Ok(Level::Alert));
assert_eq!("CRIT".parse::<Level>(), Ok(Level::Crit));
assert_eq!("error".parse::<Level>(), Ok(Level::Error));
assert_eq!("warn".parse::<Level>(), Ok(Level::Warn));
assert_eq!("notice".parse::<Level>(), Ok(Level::Notice));
assert_eq!("info".parse::<Level>(), Ok(Level::Info));
assert_eq!("debug1".parse::<Level>(), Ok(Level::Debug1));
assert_eq!("debug2".parse::<Level>(), Ok(Level::Debug2));
assert_eq!("debug3".parse::<Level>(), Ok(Level::Debug3));
assert_eq!("debug4".parse::<Level>(), Ok(Level::Debug4));
assert_eq!("debug5".parse::<Level>(), Ok(Level::Debug5));
assert_eq!("debug6".parse::<Level>(), Ok(Level::Debug6));
assert_eq!("debug7".parse::<Level>(), Ok(Level::Debug7));
assert_eq!("debug8".parse::<Level>(), Ok(Level::Debug8));
assert_eq!("debug9".parse::<Level>(), Ok(Level::Debug9));
assert_eq!("debug10".parse::<Level>(), Ok(Level::Debug10));
assert_eq!("debug11".parse::<Level>(), Err(UnknownLogLevel));
}
#[test]
fn test_level_to_str() {
assert_eq!(Level::Off.to_string(), "off");
assert_eq!(Level::Emerg.to_string(), "emerg");
assert_eq!(Level::Alert.to_string(), "alert");
assert_eq!(Level::Crit.to_string(), "crit");
assert_eq!(Level::Error.to_string(), "error");
assert_eq!(Level::Warn.to_string(), "warn");
assert_eq!(Level::Notice.to_string(), "notice");
assert_eq!(Level::Info.to_string(), "info");
assert_eq!(Level::Debug1.to_string(), "debug1");
assert_eq!(Level::Debug2.to_string(), "debug2");
assert_eq!(Level::Debug3.to_string(), "debug3");
assert_eq!(Level::Debug4.to_string(), "debug4");
assert_eq!(Level::Debug5.to_string(), "debug5");
assert_eq!(Level::Debug6.to_string(), "debug6");
assert_eq!(Level::Debug7.to_string(), "debug7");
assert_eq!(Level::Debug8.to_string(), "debug8");
assert_eq!(Level::Debug9.to_string(), "debug9");
assert_eq!(Level::Debug10.to_string(), "debug10");
}
#[test]
fn test_level_from_usize() {
assert_eq!(Level::iter().nth(1).unwrap_or(Level::Off), Level::Emerg);
assert_eq!(Level::iter().nth(6).unwrap_or(Level::Off), Level::Notice);
assert_eq!(Level::iter().nth(42).unwrap_or(Level::Off), Level::Off);
}
}