use crate::console::Color;
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Level {
Trace = 0,
Debug = 1,
Info = 2,
Warning = 3,
Error = 4,
Fatal = 5,
Panic = 6,
}
pub const ALL_LEVELS: [Level; 7] = [Level::Trace, Level::Debug, Level::Info, Level::Warning, Level::Error, Level::Fatal, Level::Panic];
pub const LEVEL_SHORT_NAME_MAX_LENGTH: usize = 3;
pub const LEVEL_LONG_NAME_MAX_LENGTH: usize = 7;
impl Level {
pub fn value(&self) -> u8 {
*self as u8
}
pub fn covers(&self, other: &Level) -> bool {
other.value() >= self.value()
}
pub fn includes(&self, other: &Level) -> bool {
other.value() <= self.value()
}
pub fn color(&self) -> Color {
match *self {
Self::Trace => Color::White,
Self::Debug => Color::BrightBlue,
Self::Info => Color::Green,
Self::Warning => Color::Yellow,
Self::Error => Color::Red,
Self::Fatal => Color::BrightRed,
Self::Panic => Color::Magenta,
}
}
pub fn as_str(&self) -> &'static str {
match *self {
Self::Trace => "trace",
Self::Debug => "debug",
Self::Info => "info",
Self::Warning => "warning",
Self::Error => "error",
Self::Fatal => "fatal",
Self::Panic => "panic",
}
}
pub fn as_long_str(&self) -> &'static str {
match *self {
Self::Trace => "TRACE",
Self::Debug => "DEBUG",
Self::Info => "INFO",
Self::Warning => "WARNING",
Self::Error => "ERROR",
Self::Fatal => "FATAL",
Self::Panic => "PANIC",
}
}
pub fn as_short_str(&self) -> &'static str {
match *self {
Self::Trace => "TRA",
Self::Debug => "DBG",
Self::Info => "INF",
Self::Warning => "WRN",
Self::Error => "ERR",
Self::Fatal => "FAT",
Self::Panic => "PNC",
}
}
pub fn syslog_severity(&self) -> u16 {
match *self {
Self::Trace => 7, Self::Debug => 7, Self::Info => 6, Self::Warning => 4, Self::Error => 3, Self::Fatal => 1, Self::Panic => 0, }
}
}
impl ToString for Level {
fn to_string(&self) -> String {
self.as_str().into()
}
}
impl TryFrom<&str> for Level {
type Error = &'static str;
fn try_from(name: &str) -> Result<Self, <Level as TryFrom<&str>>::Error> {
for l in ALL_LEVELS {
if name.eq_ignore_ascii_case(l.as_str()) {
return Ok(l);
}
}
Err("invalid Level name")
}
}
impl TryFrom<u8> for Level {
type Error = &'static str;
fn try_from(value: u8) -> Result<Self, <Level as TryFrom<u8>>::Error> {
for l in ALL_LEVELS {
if value == l.value() {
return Ok(l);
}
}
Err("invalid Level value")
}
}
#[cfg(test)]
mod from {
use super::*;
#[test]
fn name() {
assert_eq!(Level::try_from(""), Err("invalid Level name"));
assert_eq!(Level::try_from("boo"), Err("invalid Level name"));
assert_eq!(Level::try_from("iNfO"), Ok(Level::Info));
assert_eq!(Level::try_from("warNINg"), Ok(Level::Warning));
assert_eq!(Level::try_from("pnc"), Err("invalid Level name"));
assert_eq!(Level::try_from("panic"), Ok(Level::Panic));
assert_eq!(Level::try_from("tRa"), Err("invalid Level name"));
assert_eq!(Level::try_from("TRACE"), Ok(Level::Trace));
}
#[test]
fn value() {
assert_eq!(Level::try_from(0), Ok(Level::Trace));
assert_eq!(Level::try_from(1), Ok(Level::Debug));
assert_eq!(Level::try_from(2), Ok(Level::Info));
assert_eq!(Level::try_from(3), Ok(Level::Warning));
assert_eq!(Level::try_from(4), Ok(Level::Error));
assert_eq!(Level::try_from(5), Ok(Level::Fatal));
assert_eq!(Level::try_from(6), Ok(Level::Panic));
assert_eq!(Level::try_from(7), Err("invalid Level value"));
}
}