1use serde::{Deserialize, Serialize};
9use std::{fmt, str::FromStr};
10
11#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
14pub struct Metadata {
15 level: Level,
17
18 target: &'static str,
20
21 module_path: &'static str,
23
24 file: &'static str,
26
27 line: u32,
29
30 location: &'static str,
32}
33
34impl Metadata {
35 pub const fn new(
36 level: Level, target: &'static str, module_path: &'static str,
37 file: &'static str, line: u32, location: &'static str,
38 ) -> Self {
39 Self {
40 level,
41 target,
42 module_path,
43 file,
44 line,
45 location,
46 }
47 }
48
49 pub fn enabled(&self) -> bool { crate::logger::enabled(self) }
50
51 pub fn level(&self) -> Level { self.level }
52
53 pub fn target(&self) -> &'static str { self.target }
54
55 pub fn module_path(&self) -> &'static str { self.module_path }
56
57 pub fn file(&self) -> &'static str { self.file }
58
59 pub fn line(&self) -> u32 { self.line }
60
61 pub fn location(&self) -> &'static str { self.location }
62}
63
64static LOG_LEVEL_NAMES: &[&str] = &["ERROR", "WARN", "INFO", "DEBUG", "TRACE"];
65
66#[repr(usize)]
69#[derive(
70 Copy,
71 Clone,
72 PartialEq,
73 Eq,
74 PartialOrd,
75 Ord,
76 Debug,
77 Hash,
78 Serialize,
79 Deserialize,
80)]
81#[serde(rename_all = "UPPERCASE")]
82pub enum Level {
83 Error = 0,
87 Warn,
91 Info,
95 Debug,
99 Trace,
103}
104
105impl Level {
106 fn from_usize(idx: usize) -> Option<Self> {
107 let lvl = match idx {
108 0 => Level::Error,
109 1 => Level::Warn,
110 2 => Level::Info,
111 3 => Level::Debug,
112 4 => Level::Trace,
113 _ => return None,
114 };
115
116 Some(lvl)
117 }
118}
119
120#[derive(Debug)]
122pub struct LevelParseError;
123
124impl FromStr for Level {
125 type Err = LevelParseError;
126
127 fn from_str(level: &str) -> Result<Level, Self::Err> {
128 LOG_LEVEL_NAMES
129 .iter()
130 .position(|name| name.eq_ignore_ascii_case(level))
131 .map(|idx| Level::from_usize(idx).unwrap())
132 .ok_or(LevelParseError)
133 }
134}
135
136impl fmt::Display for Level {
137 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
138 fmt.pad(LOG_LEVEL_NAMES[*self as usize])
139 }
140}