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}