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