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.lock().unwrap()
106/// .format_log(&LogStruct::error("Much bad!"));
107/// print!("{}", &log);
108/// ```
109#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
110pub struct LogStruct {
111 /// The log message
112 pub message: String,
113 /// The type of the log (e.g., `Debug`, `Info`, `Warning`, etc.)
114 pub log_type: LogType,
115 /// The date and time at which the log struct was instantiated
116 pub datetime: DateTime<Local>,
117}
118
119impl LogStruct {
120 /// Returns a `LogStruct` with **debug** preset applied.
121 ///
122 /// # Examples
123 ///
124 /// Creating a debug log:
125 /// ```
126 /// # use prettylogger::config::LogStruct;
127 /// let debug_log = LogStruct::debug("This is a debug log!");
128 /// ```
129 pub fn debug(message: &str) -> LogStruct {
130 LogStruct {
131 message: message.to_string(),
132 log_type: LogType::Debug,
133 datetime: Local::now(),
134 }
135 }
136
137 /// Returns a `LogStruct` with **info** preset applied.
138 ///
139 /// # Examples
140 ///
141 /// Creating an informative log:
142 /// ```
143 /// # use prettylogger::config::LogStruct;
144 /// let info_log = LogStruct::info("This is an info log!");
145 /// ```
146 pub fn info(message: &str) -> LogStruct {
147 LogStruct {
148 message: message.to_string(),
149 log_type: LogType::Info,
150 datetime: Local::now(),
151 }
152 }
153
154 /// Returns a `LogStruct` with **warning** preset applied.
155 ///
156 /// # Examples
157 ///
158 /// Creating a warning log:
159 /// ```
160 /// # use prettylogger::config::LogStruct;
161 /// let warning_log = LogStruct::warning("This is a warning!");
162 /// ```
163 pub fn warning(message: &str) -> LogStruct {
164 LogStruct {
165 message: message.to_string(),
166 log_type: LogType::Warning,
167 datetime: Local::now(),
168 }
169 }
170
171 /// Returns a `LogStruct` with **error** preset applied.
172 ///
173 /// # Examples
174 ///
175 /// Creating an error log:
176 /// ```
177 /// # use prettylogger::config::LogStruct;
178 /// let error_log = LogStruct::error("This is an error!");
179 /// ```
180 pub fn error(message: &str) -> LogStruct {
181 LogStruct {
182 message: message.to_string(),
183 log_type: LogType::Err,
184 datetime: Local::now(),
185 }
186 }
187
188 /// Returns a `LogStruct` with **fatal error** preset applied.
189 ///
190 /// # Examples
191 ///
192 /// Creating a fatal error log:
193 /// ```
194 /// # use prettylogger::config::LogStruct;
195 /// let fatal_log = LogStruct::fatal_error("This is a fatal error!");
196 /// ```
197 pub fn fatal_error(message: &str) -> LogStruct {
198 LogStruct {
199 message: message.to_string(),
200 log_type: LogType::FatalError,
201 datetime: Local::now(),
202 }
203 }
204}
205
206impl Display for LogStruct {
207 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
208 return write!(
209 f,
210 "Log: {}\nType: {:?}\nDateTime: {}",
211 self.message,
212 self.log_type,
213 self.datetime
214 )
215 }
216}
217
218
219impl std::fmt::Display for Verbosity {
220 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
221 let level_str = match *self {
222 Verbosity::All => "All",
223 Verbosity::Standard => "Standard",
224 Verbosity::Quiet => "Quiet",
225 Verbosity::ErrorsOnly => "ErrorsOnly",
226 };
227 return write!(f, "{}", level_str)
228 }
229}
230
231impl TryFrom<i32> for Verbosity {
232 type Error = Error;
233 fn try_from(value: i32) -> Result<Self, Self::Error> {
234 match value {
235 0 => Ok(Verbosity::All),
236 1 => Ok(Verbosity::Standard),
237 2 => Ok(Verbosity::Quiet),
238 3 => Ok(Verbosity::ErrorsOnly),
239 _ => Err(Error::new("Invalid value. Please provide a value in range from 0 to 3.")),
240 }
241 }
242}
243
244impl AsRef<str> for Verbosity {
245 fn as_ref(&self) -> &str {
246 match self {
247 Verbosity::All => "All",
248 Verbosity::Standard => "Standard",
249 Verbosity::Quiet => "Quiet",
250 Verbosity::ErrorsOnly => "ErrorsOnly",
251 }
252 }
253}
254
255
256impl Display for OnDropPolicy {
257 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
258 let level_str = match *self {
259 OnDropPolicy::IgnoreLogFileLock => "IgnoreLogFileLock",
260 OnDropPolicy::DiscardLogBuffer => "DiscardLogBuffer",
261 };
262 return write!(f, "{}", level_str)
263 }
264}
265
266
267impl TryFrom<i32> for LogType {
268 type Error = Error;
269 fn try_from(value: i32) -> Result<Self, Self::Error> {
270 match value {
271 0 => Ok(LogType::Debug),
272 1 => Ok(LogType::Info),
273 2 => Ok(LogType::Warning),
274 3 => Ok(LogType::Err),
275 4 => Ok(LogType::FatalError),
276 _ => Err(Error::new("Invalid value. Please provide a value in range from 0 to 4.")),
277 }
278 }
279}
280
281impl Display for LogType {
282 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
283 let level_str = match *self {
284 LogType::Debug => "Debug",
285 LogType::Info => "Info",
286 LogType::Warning => "Warning",
287 LogType::Err => "Error",
288 LogType::FatalError => "FatalError",
289 };
290 return write!(f, "{}", level_str)
291 }
292}
293
294impl AsRef<str> for LogType {
295 fn as_ref(&self) -> &str {
296 match self {
297 LogType::Debug => "Debug",
298 LogType::Info => "Info",
299 LogType::Warning => "Warning",
300 LogType::Err => "Err",
301 LogType::FatalError => "FatalError",
302 }
303 }
304}