prettylogger/
setters.rs

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