use std::cmp::Ordering;
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use serde::Serialize;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
pub enum Level {
Emergency,
Alert,
Critical,
Error,
Warning,
Notice,
Info,
Debug,
Custom(String, Option<i8>),
}
impl Level {
pub fn name(&self) -> String {
match self {
Level::Emergency => "emergency".into(),
Level::Alert => "alert".into(),
Level::Critical => "critical".into(),
Level::Error => "error".into(),
Level::Warning => "warning".into(),
Level::Notice => "notice".into(),
Level::Info => "info".into(),
Level::Debug => "debug".into(),
Level::Custom(s, _) => s.to_lowercase(),
}
}
pub fn severity(&self) -> i8 {
match self {
Level::Debug => 7,
Level::Info => 6,
Level::Notice => 5,
Level::Warning => 4,
Level::Error => 3,
Level::Critical => 2,
Level::Alert => 1,
Level::Emergency => 0,
Level::Custom(_, Some(v)) => *v,
Level::Custom(_, None) => -1,
}
}
pub fn above(&self, other: &Self) -> bool {
self.severity() < other.severity()
}
pub fn below(&self, other: &Self) -> bool {
self.severity() > other.severity()
}
pub fn from_name(name: &str) -> Self {
match name.to_lowercase().as_str() {
"debug" => Level::Debug,
"info" => Level::Info,
"notice" => Level::Notice,
"warning" => Level::Warning,
"error" => Level::Error,
"critical" => Level::Critical,
"alert" => Level::Alert,
"emergency" => Level::Emergency,
other => Level::Custom(other.to_string(), None),
}
}
pub fn from_severity(severity: i8) -> Self {
match severity {
0 => Level::Emergency,
1 => Level::Alert,
2 => Level::Critical,
3 => Level::Error,
4 => Level::Warning,
5 => Level::Notice,
6 => Level::Info,
7 => Level::Debug,
other => Level::Custom(other.to_string(), Some(other)),
}
}
}
impl Display for Level {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(self.name().as_ref())
}
}
impl FromStr for Level {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::from_name(s))
}
}
impl PartialOrd for Level {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Level {
fn cmp(&self, other: &Self) -> Ordering {
self.severity().cmp(&other.severity()).reverse()
}
}