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}