prettylogger/config.rs
1//! Implements various types used to customize `Logger`, `LogFormatter` and
2//! output streams' behavior.
3
4/// Implements various types used to customize `Logger`, `LogFormatter` and
5/// output streams' behavior.
6use serde::{Serialize, Deserialize};
7use std::fmt::{Display, Formatter};
8use chrono::{Local, DateTime};
9use crate::Error;
10
11/// Used to set the verbosity of a `Logger`.
12///
13/// # Examples
14///
15/// Setting `Logger` verbosity:
16/// ```
17/// # use prettylogger::{Logger, config::Verbosity};
18/// # let mut logger = Logger::default();
19/// logger.set_verbosity(Verbosity::Quiet);
20/// ```
21#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Debug, Default,
22 Serialize, Deserialize)]
23pub enum Verbosity {
24 /// Display all logs
25 All = 0,
26 #[default]
27 /// Only filter debug logs
28 Standard = 1,
29 /// Only display errors and warnings
30 Quiet = 2,
31 /// Only display errors
32 ErrorsOnly = 3,
33}
34
35/// Defines the policy for handling log file flushing when a `FileStream`
36/// instance is dropped.
37///
38/// # Examples
39///
40/// Setting on drop policy:
41/// ```rust
42/// # use prettylogger::{
43/// # output::FileStream,
44/// # config::OnDropPolicy,
45/// # };
46/// let mut file_stream = FileStream::default();
47/// file_stream.set_on_drop_policy(OnDropPolicy::IgnoreLogFileLock);
48/// ```
49#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default,
50 Serialize, Deserialize)]
51pub enum OnDropPolicy {
52 /// Ignore the log file lock and write to the file anyway. This may cause
53 /// race conditions
54 IgnoreLogFileLock,
55 #[default]
56 /// Respect the log file lock and don't write to the log file. This may
57 /// cause data loss
58 DiscardLogBuffer,
59}
60
61
62/// Represents different types of log messages.
63///
64/// Used internally by `LogStruct`, `LogFormatter`, `Logger` and various log
65/// streams.
66///
67/// # Examples
68///
69/// Setting log type of a `LogStruct`:
70/// ```rust
71/// # use prettylogger::config::{
72/// # LogStruct,
73/// # LogType,
74/// # };
75/// let mut log = LogStruct::debug("This is going to be an error message");
76/// log.log_type = LogType::Err;
77/// ```
78#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default,
79 Serialize, Deserialize)]
80pub enum LogType {
81 /// A debug log
82 Debug = 0,
83 #[default]
84 /// A standard, informative message
85 Info = 1,
86 /// A warning
87 Warning = 2,
88 /// An error
89 Err = 3,
90 /// A critical error
91 FatalError = 4,
92}
93
94/// Represents a single log entry.
95///
96/// Used internally by `LogFormatter`, `Logger` and various log streams.
97///
98/// # Examples
99///
100/// Print a formatted log message:
101/// ```
102/// # use prettylogger::{Logger, config::LogStruct};
103/// # let mut logger = Logger::default();
104/// // Get a formatted log message from a `LogStruct` instance
105/// let log = logger.formatter.format_log(&LogStruct::error("Much bad!"));
106/// print!("{}", &log);
107/// ```
108#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
109pub struct LogStruct {
110 /// The log message
111 pub message: String,
112 /// The type of the log (e.g., `Debug`, `Info`, `Warning`, etc.)
113 pub log_type: LogType,
114 /// The date and time at which the log struct was instantiated
115 pub datetime: DateTime<Local>,
116}
117
118impl LogStruct {
119 /// Returns a `LogStruct` with **debug** preset applied.
120 ///
121 /// # Examples
122 ///
123 /// Creating a debug log:
124 /// ```
125 /// # use prettylogger::config::LogStruct;
126 /// let debug_log = LogStruct::debug("This is a debug log!");
127 /// ```
128 pub fn debug(message: &str) -> LogStruct {
129 LogStruct {
130 message: message.to_string(),
131 log_type: LogType::Debug,
132 datetime: Local::now(),
133 }
134 }
135
136 /// Returns a `LogStruct` with **info** preset applied.
137 ///
138 /// # Examples
139 ///
140 /// Creating an informative log:
141 /// ```
142 /// # use prettylogger::config::LogStruct;
143 /// let info_log = LogStruct::info("This is an info log!");
144 /// ```
145 pub fn info(message: &str) -> LogStruct {
146 LogStruct {
147 message: message.to_string(),
148 log_type: LogType::Info,
149 datetime: Local::now(),
150 }
151 }
152
153 /// Returns a `LogStruct` with **warning** preset applied.
154 ///
155 /// # Examples
156 ///
157 /// Creating a warning log:
158 /// ```
159 /// # use prettylogger::config::LogStruct;
160 /// let warning_log = LogStruct::warning("This is a warning!");
161 /// ```
162 pub fn warning(message: &str) -> LogStruct {
163 LogStruct {
164 message: message.to_string(),
165 log_type: LogType::Warning,
166 datetime: Local::now(),
167 }
168 }
169
170 /// Returns a `LogStruct` with **error** preset applied.
171 ///
172 /// # Examples
173 ///
174 /// Creating an error log:
175 /// ```
176 /// # use prettylogger::config::LogStruct;
177 /// let error_log = LogStruct::error("This is an error!");
178 /// ```
179 pub fn error(message: &str) -> LogStruct {
180 LogStruct {
181 message: message.to_string(),
182 log_type: LogType::Err,
183 datetime: Local::now(),
184 }
185 }
186
187 /// Returns a `LogStruct` with **fatal error** preset applied.
188 ///
189 /// # Examples
190 ///
191 /// Creating a fatal error log:
192 /// ```
193 /// # use prettylogger::config::LogStruct;
194 /// let fatal_log = LogStruct::fatal_error("This is a fatal error!");
195 /// ```
196 pub fn fatal_error(message: &str) -> LogStruct {
197 LogStruct {
198 message: message.to_string(),
199 log_type: LogType::FatalError,
200 datetime: Local::now(),
201 }
202 }
203}
204
205impl Display for LogStruct {
206 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
207 return write!(
208 f,
209 "Log: {}\nType: {:?}\nDateTime: {}",
210 self.message,
211 self.log_type,
212 self.datetime
213 )
214 }
215}
216
217
218impl std::fmt::Display for Verbosity {
219 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
220 let level_str = match *self {
221 Verbosity::All => "All",
222 Verbosity::Standard => "Standard",
223 Verbosity::Quiet => "Quiet",
224 Verbosity::ErrorsOnly => "ErrorsOnly",
225 };
226 return write!(f, "{}", level_str)
227 }
228}
229
230impl TryFrom<i32> for Verbosity {
231 type Error = Error;
232 fn try_from(value: i32) -> Result<Self, Self::Error> {
233 match value {
234 0 => Ok(Verbosity::All),
235 1 => Ok(Verbosity::Standard),
236 2 => Ok(Verbosity::Quiet),
237 3 => Ok(Verbosity::ErrorsOnly),
238 _ => Err(Error::new("Invalid value. Please provide a value in range from 0 to 3.")),
239 }
240 }
241}
242
243impl AsRef<str> for Verbosity {
244 fn as_ref(&self) -> &str {
245 match self {
246 Verbosity::All => "All",
247 Verbosity::Standard => "Standard",
248 Verbosity::Quiet => "Quiet",
249 Verbosity::ErrorsOnly => "ErrorsOnly",
250 }
251 }
252}
253
254
255impl Display for OnDropPolicy {
256 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
257 let level_str = match *self {
258 OnDropPolicy::IgnoreLogFileLock => "IgnoreLogFileLock",
259 OnDropPolicy::DiscardLogBuffer => "DiscardLogBuffer",
260 };
261 return write!(f, "{}", level_str)
262 }
263}
264
265
266impl TryFrom<i32> for LogType {
267 type Error = Error;
268 fn try_from(value: i32) -> Result<Self, Self::Error> {
269 match value {
270 0 => Ok(LogType::Debug),
271 1 => Ok(LogType::Info),
272 2 => Ok(LogType::Warning),
273 3 => Ok(LogType::Err),
274 4 => Ok(LogType::FatalError),
275 _ => Err(Error::new("Invalid value. Please provide a value in range from 0 to 4.")),
276 }
277 }
278}
279
280impl Display for LogType {
281 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
282 let level_str = match *self {
283 LogType::Debug => "Debug",
284 LogType::Info => "Info",
285 LogType::Warning => "Warning",
286 LogType::Err => "Error",
287 LogType::FatalError => "FatalError",
288 };
289 return write!(f, "{}", level_str)
290 }
291}
292
293impl AsRef<str> for LogType {
294 fn as_ref(&self) -> &str {
295 match self {
296 LogType::Debug => "Debug",
297 LogType::Info => "Info",
298 LogType::Warning => "Warning",
299 LogType::Err => "Err",
300 LogType::FatalError => "FatalError",
301 }
302 }
303}