flogging/logger/level.rs
1//
2// File Name: level.rs
3// Project Name: flogging
4//
5// Copyright (C) 2025 Bradley Willcott
6//
7// SPDX-License-Identifier: GPL-3.0-or-later
8//
9// This library (crate) is free software: you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation, either version 3 of the License, or
12// (at your option) any later version.
13//
14// This library (crate) is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License
20// along with this library (crate). If not, see <https://www.gnu.org/licenses/>.
21//
22
23//!
24//! # Log Entry Level
25//!
26//! This module provides the enum containing the possible log entry levels.
27//! The order in which they are listed within the enum, enables logging at that level
28//! and at all higher levels.
29//!
30//! The levels in descending order are:
31//!
32//! - SEVERE (highest level)
33//! - WARNING
34//! - INFO
35//! - CONFIG
36//! - FINE
37//! - FINER
38//! - FINEST (lowest level)
39//!
40//! In addition there is a level **OFF** that can be used to turn off logging.
41
42use std::{fmt, str::FromStr};
43use strum::{EnumIter, IntoEnumIterator};
44
45///
46/// Log entry level setting.
47///
48/// Default level: INFO.
49///
50// #[allow(unused)]
51#[derive(Debug, Clone, Default, PartialEq, PartialOrd, EnumIter)]
52pub enum Level {
53 ///
54 /// ALL is a special level that can be used to turn on logging
55 /// for all levels.
56 ///
57 ALL,
58
59 ///
60 /// FINEST indicates a highly detailed tracing message.
61 ///
62 FINEST,
63
64 ///
65 /// FINER indicates a fairly detailed tracing message.
66 /// Suggest logging calls for entering, returning,
67 /// or `Error`s, such as returned via `Result`, are traced at
68 /// this level.
69 ///
70 FINER,
71
72 ///
73 /// FINE is a message level providing tracing information.
74 ///
75 /// All of FINE, FINER, and FINEST are intended for relatively
76 /// detailed tracing. The exact meaning of the three levels will
77 /// vary between subsystems, but in general, FINEST should be
78 /// used for the most voluminous detailed output, FINER for somewhat
79 /// less detailed output, and FINE for the lowest volume (and most
80 /// important) messages.
81 ///
82 /// In general the FINE level should be used for information that
83 /// will be broadly interesting to developers who do not have a
84 /// specialized interest in the specific subsystem.
85 ///
86 /// FINE messages might include things like minor (recoverable)
87 /// failures. Issues indicating potential performance problems are
88 /// also worth logging as FINE.
89 ///
90 FINE,
91
92 ///
93 /// CONFIG is a message level for static configuration messages.
94 ///
95 /// CONFIG messages are intended to provide a variety of static
96 /// configuration information, to assist in debugging problems
97 /// that may be associated with particular configurations.
98 ///
99 /// For example, a CONFIG message might include the CPU type, the
100 /// graphics depth, the GUI look-and-feel, etc.
101 ///
102 CONFIG,
103
104 ///
105 /// INFO is a message level for informational messages.
106 ///
107 /// Typically INFO messages will be written to the console or its
108 /// equivalent. So the INFO level should only be used for reasonably
109 /// significant messages that will make sense to end users and system
110 /// administrators.
111 ///
112 /// \[default level]
113 ///
114 #[default]
115 INFO,
116
117 ///
118 /// WARNING is a message level indicating a potential problem.
119 ///
120 /// In general WARNING messages should describe events that will be
121 /// of interest to end users or system managers, or which indicate
122 /// potential problems.
123 ///
124 WARNING,
125
126 ///
127 /// SEVERE is a message level indicating a serious failure.
128 ///
129 /// In general SEVERE messages should describe events that are of
130 /// considerable importance and which will prevent normal program
131 /// execution. They should be reasonably intelligible to end users
132 /// and to system administrators.
133 ///
134 SEVERE,
135
136 ///
137 /// OFF is a special level that can be used to turn off logging.
138 ///
139 OFF,
140}
141
142impl Level {
143 ///
144 /// Converts a level to its string version.
145 ///
146 pub const fn as_str(&self) -> &'static str {
147 match self {
148 Level::ALL => "ALL",
149 Level::FINEST => "FINEST",
150 Level::FINER => "FINER",
151 Level::FINE => "FINE",
152 Level::CONFIG => "CONFIG",
153 Level::INFO => "INFO",
154 Level::WARNING => "WARNING",
155 Level::SEVERE => "SEVERE",
156 Level::OFF => "OFF",
157 }
158 }
159}
160
161impl fmt::Display for Level {
162 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163 self.as_str().fmt(f)
164 }
165}
166
167#[allow(dead_code)]
168#[derive(Debug)]
169pub struct LevelError {
170 msg: String,
171}
172
173impl FromStr for Level {
174 type Err = LevelError;
175
176 fn from_str(s: &str) -> Result<Self, Self::Err> {
177 match s {
178 "ALL" => Ok(Level::ALL),
179 "FINEST" => Ok(Level::FINEST),
180 "FINER" => Ok(Level::FINER),
181 "FINE" => Ok(Level::FINE),
182 "CONFIG" => Ok(Level::CONFIG),
183 "INFO" => Ok(Level::INFO),
184 "WARNING" => Ok(Level::WARNING),
185 "SEVERE" => Ok(Level::SEVERE),
186 "OFF" => Ok(Level::OFF),
187 _ => Err(LevelError {
188 msg: format!("Unknown Level: {s}"),
189 }),
190 }
191 }
192}
193
194#[cfg(test)]
195mod tests {
196 use super::*;
197
198 #[test]
199 fn compare_levels() {
200 let log_level = Level::default();
201 let b = Level::FINE;
202
203 println!("\n|{log_level}|\n");
204
205 assert!(b < log_level);
206 }
207
208 #[test]
209 fn check_conversions() {
210 for level in Level::iter() {
211 let lstr = level.as_str();
212 let l = Level::from_str(lstr).unwrap();
213 assert_eq!(level, l);
214 }
215
216 assert!(Level::from_str("DEBUG").is_err());
217 }
218}