prettylogger/
setters.rs

1use crate::*;
2use crate::{
3    colors::*, fileio::*, config::*,
4};
5use std::io::{Error, ErrorKind};
6
7impl Logger {
8    /// Sets logger `verbosity`.
9    ///
10    /// # Example
11    /// ```
12    /// # use prettylogger::{Logger, config::Verbosity};
13    /// # let mut logger = Logger::default();
14    /// logger.set_verbosity(Verbosity::Quiet);
15    /// ```
16    pub fn set_verbosity<I: Into<Verbosity>>(&mut self, verbosity: I) {
17        self.verbosity = verbosity.into();
18    }
19
20    /// Toggles log filtering.
21    /// * **true**: logs will get filtered based on verbosity
22    /// * **false**: log filtering will be disabled globally
23    pub fn toggle_log_filtering<I: Into<bool>>(&mut self, enabled: I) {
24        self.filtering_enabled = enabled.into();
25    }
26
27    /// Toggles colored log headers.
28    /// * `true`: Log headers will have colors
29    /// * `false`: No colors :(
30    pub fn toggle_log_header_color<I: Into<bool>>(&mut self, enabled: I) {
31        self.log_header_color_enabled = enabled.into();
32    }
33
34    /// Sets **debug log header** color.
35    pub fn set_debug_color<I: Into<Color>>(&mut self, color: I) {
36        self.debug_color = color.into();
37    }
38
39    /// Sets **info log header** color.
40    pub fn set_info_color<I: Into<Color>>(&mut self, color: I) {
41        self.info_color = color.into();
42    }
43
44    /// Sets **warning header** color.
45    pub fn set_warning_color<I: Into<Color>>(&mut self, color: I) {
46        self. warning_color = color.into();
47    }
48
49    /// Sets **error header** color.
50    pub fn set_error_color<I: Into<Color>>(&mut self, color: I) {
51        self.error_color = color.into();
52    }
53
54    /// Sets **fatal error header** color.
55    pub fn set_fatal_color<I: Into<Color>>(&mut self, color: I) {
56        self.fatal_color = color.into();
57    }
58
59    /// Sets **debug log header** format.
60    pub fn set_debug_header(&mut self, header: &str) {
61        self.debug_header = header.to_string();
62    }
63
64    /// Sets **info log header** format.
65    pub fn set_info_header(&mut self, header: &str) {
66        self.info_header = header.to_string();
67    }
68
69    /// Sets **warning header** format.
70    pub fn set_warning_header(&mut self, header: &str) {
71        self.warning_header = header.to_string();
72    }
73
74    /// Sets **error header** format.
75    pub fn set_error_header(&mut self, header: &str) {
76        self.error_header = header.to_string();
77    }
78
79    /// Sets **fatal error header** format.
80    pub fn set_fatal_header(&mut self, header: &str) {
81        self.fatal_header = header.to_string();
82    }
83
84    /// Sets datetime format.
85    pub fn set_datetime_format(&mut self, format: &str) {
86        self.datetime_format = String::from(format);
87    }
88
89    /// Sets the log format.
90    ///
91    /// There are three placeholders in a log format string (you can place
92    /// multiple placeholders of the same type in a format string):
93    /// * `%c`: Ascending log count starting at 1.
94    /// * `%d`: The timestamp.
95    /// * `%h`: The header indicating the log type (e.g., debug, error, etc.)
96    /// * `%m`: The log message (this placeholder is mandatory, you will get
97    /// an error if you don't include this in your log format).
98    ///
99    /// # Example
100    /// ```
101    /// # use prettylogger::Logger;
102    /// # let mut l = Logger::default();
103    /// l.set_log_format("<l> <h>%h</h> <m>%m</m> </l>");
104    /// l.error("lorem ipsum");
105    /// ```
106    ///
107    /// Returns an error when the `%m` placeholder is missing.
108    pub fn set_log_format(&mut self, format: &str) -> Result<(), String> {
109        if format.contains("%m") {
110            self.log_format = String::from(format);
111            self.show_datetime = format.contains("%d");
112            Ok(())
113        }
114        else {
115            Err(String::from("Expected a message placeholder!"))
116        }
117    }
118
119    /// Sets log file path.
120    ///
121    /// Returns an error if the path is inaccessible.
122    ///
123    /// [File logging documentation](https://github.com/tpaau-17DB/libprettylogger?tab=readme-ov-file#file-logging)
124    ///
125    /// # Example
126    /// ```
127    /// # use prettylogger::Logger;
128    /// # let mut logger = Logger::default();
129    /// # let mut path = std::env::temp_dir();
130    /// # path.push("libprettylogger-tests/set_log_file_path.log");
131    /// # let path = &path.to_str().unwrap().to_string();
132    /// # logger.set_log_file_path(path);
133    /// // Set the log file path first:
134    /// logger.set_log_file_path(path);
135    /// // Then enable file logging:
136    /// logger.toggle_file_logging(true);
137    /// ```
138    pub fn set_log_file_path(&mut self, path: &str) -> Result<(), Error> {
139        let path: &str = &expand_env_vars(&expand_tilde(path));
140        if is_file_writable(path) {
141            self.log_file_path = path.to_string();
142            overwrite_file(path, "")
143            .map_err(|e| {
144                    self.error(&format!("Failed to open file '{}' for writing!",
145                        self.log_file_path));
146                    Error::new(ErrorKind::Other,
147                        format!("Failed to overwrite file: {}", e))
148                })?;
149            Ok(())
150        }
151        else {
152            self.error(&format!("Failed to open file '{}' for writing!",
153                self.log_file_path));
154            Err(Error::new(ErrorKind::PermissionDenied,
155                "File is not writable!"))
156        }
157    }
158
159    /// Toggles file logging.
160    ///
161    /// Before enabling file logging, ensure that the log file path is set.
162    /// This is because this method checks if the log file is writable. If the
163    /// log file path is not set, or the file is not writable, enabling file
164    /// logging will result in an error.
165    ///
166    /// # Example
167    /// ```
168    /// # use prettylogger::Logger;
169    /// # let mut logger = Logger::default();
170    /// # let mut path = std::env::temp_dir();
171    /// # path.push("libprettylogger-tests/toggle_file_logging.log");
172    /// # let path = &path.to_str().unwrap().to_string();
173    /// # logger.set_log_file_path(path);
174    /// // Set the log file path first:
175    /// logger.set_log_file_path(path);
176    /// // Then enable file logging:
177    /// logger.toggle_file_logging(true);
178    /// ```
179    pub fn toggle_file_logging<I: Into<bool>>(&mut self, enabled: I)
180   -> Result<(), Error> {
181        if !enabled.into() {
182            self.file_logging_enabled = false;
183            Ok(())
184        }
185        else {
186            if is_file_writable(&self.log_file_path) {
187                self.file_logging_enabled = true;
188                Ok(())
189            }
190            else {
191                self.error(&format!("Failed to open file '{}' for writing!",
192                    self.log_file_path));
193                Err(Error::new(ErrorKind::PermissionDenied,
194                    "File is not writable!"))
195            }
196        }
197    }
198
199    /// Sets the maximum size of the log buffer.
200    ///
201    /// This method sets the maximum allowed size for the log buffer. When the
202    /// buffer exceeds this size, it will be automatically flushed to the log
203    /// file. If the buffer size is set to `0`, automatic flushing is disabled,
204    /// and the buffer can only be flushed manually.
205    ///
206    /// If a log file lock is active, the log buffer will not be flushed
207    /// automatically, regardless of the size limit.
208    ///
209    /// # Example
210    /// ```
211    /// # use prettylogger::Logger;
212    /// # let mut path = std::env::temp_dir();
213    /// # path.push("libprettylogger-tests/set_max_log_buffer_size.log");
214    /// # let path = &path.to_str().unwrap().to_string();
215    /// let mut logger = Logger::default();
216    /// logger.set_log_file_path(path);
217    /// logger.toggle_file_logging(true);
218    ///
219    /// // This will make `Logger` to flush the log buffer every 16 logs:
220    /// logger.set_max_log_buffer_size(16 as u32);
221    ///
222    /// let mut i = 0;
223    /// loop {
224    ///     logger.info("Yay!");
225    ///     i += 1;
226    ///     if i >= 16 {
227    ///         break;
228    ///     }
229    /// }
230    /// ```
231    pub fn set_max_log_buffer_size<I: Into<u32>>(&mut self, size: I) {
232        self.file_log_buffer_max_size = size.into();
233    }
234
235    /// Log file lock can be used to prevent race conditions when there is one
236    /// thread reading from the log file and another thread writing to the log
237    /// file.
238    ///
239    /// # WARNING: leaving this option on for a long period of time will cause
240    /// high memory usage!
241    ///
242    /// * `true`: When log file lock is enabled, logger won't flush into the
243    /// log file. Instead, it will wait until the lock is disabled. You will
244    /// not loose any logs, they will be stored in the log buffer even when it
245    /// exceeds its size limit.
246    /// * `false`: Logger will write to the log file normally.
247    pub fn toggle_log_file_lock<I: Into<bool>>(&mut self, enabled: I) {
248        self.log_file_lock = enabled.into();
249    }
250
251    /// Sets `Logger`'s on drop log file policy.
252    ///
253    /// # Example
254    /// ```
255    /// # use prettylogger::{Logger, config::OnDropPolicy};
256    /// # let mut logger = Logger::default();
257    /// logger.set_on_drop_file_policy(OnDropPolicy::IgnoreLogFileLock);
258    /// ```
259    pub fn set_on_drop_file_policy<I: Into<OnDropPolicy>>(&mut self, policy: I) {
260        self.on_drop_policy = policy.into();
261    }
262
263    /// Toggles printing logs to `stdout`.
264    /// * `true`: Logs will be printed in your terminal's `stdout`.
265    /// * `false`: No log output in your terminal.
266    pub fn toggle_console_output<I: Into<bool>>(&mut self, enabled: I) {
267        self.console_out_enabled = enabled.into();
268    }
269
270    /// Toggles the usage of a custom log buffer.
271    /// * `true`: Logs will be stored in a buffer inside `Logger` and can be
272    /// cloned using the `clone_log_buffer()` method. Be aware that this will
273    /// lead to high memory usage if turned on for a log period of time.
274    /// * `false`: Logs will not be stored in a log buffer.
275    pub fn toggle_custom_log_buffer<I: Into<bool>>(&mut self, enabled: I) {
276        self.use_custom_log_buffer = enabled.into();
277    }
278
279    /// Clears the custom log buffer.
280    pub fn clear_log_buffer(&mut self) {
281        self.custom_log_buffer = Vec::new();
282    }
283}