apollo_logger/
lib.rs

1pub mod foreground_colors;
2pub mod background_colors;
3pub mod font_mode;
4pub mod levels;
5
6use chrono::Utc;
7use crate::foreground_colors::ForegroundColors;
8use crate::background_colors::BackgroundColors;
9use crate::font_mode::FontMode;
10use crate::levels::Levels;
11
12pub struct Apollo {
13    pub logging_level: Levels
14}
15
16impl Default for Apollo {
17    fn default() -> Self {
18        Self::new()
19    }
20}
21
22impl Apollo {
23
24    /// Creates a new Apollo instance
25    ///
26    /// # Examples
27    ///
28    /// ```
29    /// use crate::apollo_logger::Apollo;
30    ///
31    /// let l = Apollo::new(); // The default logging level is Debug
32    ///
33    /// l.debug("This message will be printed");
34    /// l.warn("This message will also be printed");
35    /// ```
36    /// If you require a different logging level, please use the following code instead
37    /// ```
38    /// use crate::apollo_logger::Apollo;
39    /// use crate::apollo_logger::levels::Levels;
40    ///
41    /// let l = Apollo { logging_level: Levels::INFO };
42    ///
43    /// l.debug("This message will NOT printed");
44    /// l.warn("This message will be printed");
45    /// ```
46    pub fn new() -> Apollo {
47        Apollo { logging_level: Levels::DEBUG }
48    }
49    
50    
51    /// Gets the current time in Day/Months/Year Hour:Minute:Second.Millisecond format
52    fn get_time_as_string(&self) -> String {
53        Utc::now().format("%D %H:%M:%S%.3f").to_string()
54    }
55
56    /// Prints a message to the console with the DEBUG label
57    ///
58    /// # Arguments
59    ///
60    /// * `s`: String to print to the console
61    ///
62    /// # Examples
63    ///
64    /// ```
65    /// use crate::apollo_logger::Apollo;
66    ///
67    /// let l = Apollo::new();
68    ///
69    /// l.warn("This is an debug message");
70    /// ```
71    pub fn debug(&self, s: &str) -> Option<String> {
72
73        // Check if the logging level is high enough
74        if self.logging_level.as_u8() > Levels::DEBUG.as_u8() {
75            return None;
76        }
77
78        // Get current time
79        let current_time: String = self.get_time_as_string();
80
81        // Get colors to print
82        let date: ForegroundColors = ForegroundColors::bright_green();
83        let label: ForegroundColors = ForegroundColors::cyan();
84        let text: String = ForegroundColors::bright_white() + FontMode::bold();
85
86        // Print to console
87        let message = format!("{date}[{current_time}]\x1B[0m {label}[ DEBUG ]\x1B[0m | {text}{s}\x1B[0m");
88        println!("{message}");
89
90        Some(message)
91    }
92
93    /// Prints a message to the console with the INFO label
94    ///
95    /// # Arguments
96    ///
97    /// * `s`: String to print to the console
98    ///
99    /// # Examples
100    ///
101    /// ```
102    /// use crate::apollo_logger::Apollo;
103    ///
104    /// let l = Apollo::new();
105    ///
106    /// l.info("This is an info message");
107    /// ```
108    pub fn info(&self, s: &str) -> Option<String> {
109
110        // Check if the logging level is high enough
111        if self.logging_level.as_u8() > Levels::INFO.as_u8() {
112            return None;
113        }
114
115        // Get current time is [day/month/year hour:minute:second] format
116        let current_time: String = self.get_time_as_string();
117
118        // Get colors to print
119        let date: ForegroundColors = ForegroundColors::bright_green();
120        let label: ForegroundColors = ForegroundColors::blue();
121        let text: ForegroundColors = ForegroundColors::bright_white();
122
123        // Print to console
124        let message = format!("{date}[{current_time}]\x1B[0m {label}[ INFO  ]\x1B[0m | {text}{s}\x1B[0m");
125        println!("{message}");
126
127        Some(message)
128    }
129
130    /// Prints a message to the console with the WARN label
131    ///
132    /// # Arguments
133    ///
134    /// * `s`: String to print to the console
135    ///
136    /// # Examples
137    ///
138    /// ```
139    /// use crate::apollo_logger::Apollo;
140    ///
141    /// let l = Apollo::new();
142    ///
143    /// l.warn("This is an warning message");
144    /// ```
145    pub fn warn(&self, s: &str) -> Option<String> {
146
147        // Check if the logging level is high enough
148        if self.logging_level.as_u8() > Levels::WARN.as_u8() {
149            return None;
150        }
151
152        // Get current time is [day/month/year hour:minute:second] format
153        let current_time: String = self.get_time_as_string();
154
155        // Get colors to print
156        let date: ForegroundColors = ForegroundColors::bright_green();
157        let label: ForegroundColors = ForegroundColors::yellow();
158        let text: ForegroundColors = ForegroundColors::yellow();
159
160        // Print to console
161        let message: String = format!("{date}[{current_time}]\x1B[0m {label}[ WARN  ]\x1B[0m | {text}{s}\x1B[0m");
162        println!("{message}");
163
164        Some(message)
165    }
166
167    /// Prints a message to the console with the ERROR label
168    ///
169    /// # Arguments
170    ///
171    /// * `s`: String to print to the console
172    ///
173    /// # Examples
174    ///
175    /// ```
176    /// use crate::apollo_logger::Apollo;
177    ///
178    /// let l = Apollo::new();
179    ///
180    /// l.error("This is an error message");
181    /// ```
182    pub fn error(&self, s: &str) -> Option<String> {
183
184        // Check if the logging level is high enough
185        if self.logging_level.as_u8() > Levels::ERROR.as_u8() {
186            return None;
187        }
188
189        // Get current time is [day/month/year hour:minute:second] format
190        let current_time: String = self.get_time_as_string();
191
192        // Get colors to print
193        let date: ForegroundColors = ForegroundColors::bright_green();
194        let label: ForegroundColors = ForegroundColors::red();
195        let text: ForegroundColors = ForegroundColors::red();
196
197        // Print to console
198        let message: String = format!("{date}[{current_time}]\x1B[0m {label}[ ERROR ]\x1B[0m | {text}{s}\x1B[0m");
199        eprintln!("{message}");
200
201        Some(message)
202    }
203
204    /// Prints a message to the console with the CRITICAL label
205    ///
206    /// # Arguments
207    ///
208    /// * `s`: String to print to the console
209    ///
210    /// # Examples
211    ///
212    /// ```
213    /// use crate::apollo_logger::Apollo;
214    ///
215    /// let l = Apollo::new();
216    ///
217    /// l.critical("This is an critical message");
218    /// ```
219    pub fn critical(&self, s: &str) -> Option<String> {
220
221        // Check if the logging level is high enough
222        if self.logging_level.as_u8() > Levels::CRITICAL.as_u8() {
223            return None;
224        }
225
226        // Get current time is [day/month/year hour:minute:second] format
227        let current_time: String = self.get_time_as_string();
228
229        // Get colors to print
230        let date: ForegroundColors = ForegroundColors::bright_green();
231        let label: ForegroundColors = ForegroundColors::bright_red();
232        let text: String = ForegroundColors::bright_white() + BackgroundColors::bright_red() + FontMode::bold();
233
234        // Print to console
235        let message: String = format!("{date}[{current_time}]\x1B[0m {label}[ CRIT  ]\x1B[0m | {text}{s}\x1B[0m");
236        eprintln!("{message}");
237
238        Some(message)
239    }
240}
241
242#[cfg(test)]
243mod tests {
244    // Note this useful idiom: importing names from outer (for mod tests) scope.
245    use super::*;
246
247    /// Test if debug will log to console with default logger level
248    #[test]
249    fn test_debug() {
250        let logger = Apollo::new();
251        assert!(logger.debug("This is a test debug message").is_some());
252    }
253
254    /// Test if debug will return None when logging level is too high
255    #[test]
256    fn test_debug_under_level() {
257        let logger = Apollo { logging_level: Levels::INFO };
258        assert!(logger.debug("This is a test debug message").is_none());
259    }
260
261    /// Test if info will log to console with default logger level
262    #[test]
263    fn test_info() {
264        let logger = Apollo::new();
265        assert!(logger.info("This is a test info message").is_some());
266    }
267
268    /// Test if info will return None when logging level is too high
269    #[test]
270    fn test_info_under_level() {
271        let logger = Apollo { logging_level: Levels::WARN };
272        assert!(logger.info("This is a test info message").is_none());
273    }
274
275    /// Test if warn will log to console with default logger level
276    #[test]
277    fn test_warn() {
278        let logger = Apollo::new();
279        assert!(logger.warn("This is a test warning message").is_some());
280    }
281
282    /// Test if warn will return None when logging level is too high
283    #[test]
284    fn test_warn_under_level() {
285        let logger = Apollo { logging_level: Levels::ERROR };
286        assert!(logger.warn("This is a test warning message").is_none());
287    }
288
289    /// Test if error will log to console with default logger level
290    #[test]
291    fn test_error() {
292        let logger = Apollo::new();
293        assert!(logger.error("This is a test error message").is_some());
294    }
295
296    /// Test if error will return None when logging level is too high
297    #[test]
298    fn test_error_under_level() {
299        let logger = Apollo { logging_level: Levels::CRITICAL };
300        assert!(logger.error("This is a test error message").is_none());
301    }
302
303    /// Test if critical will log to console with default logger level
304    #[test]
305    fn test_critical() {
306        let logger = Apollo::new();
307        assert!(logger.critical("This is a test critical message").is_some());
308    }
309
310    /// Test if critical will return None when logging level is too high
311    #[test]
312    fn test_critical_under_level() {
313        let logger = Apollo { logging_level: Levels::NONE };
314        assert!(logger.critical("This is a test critical message").is_none());
315    }
316
317    /// Test if nothing gets logged when logging level is None
318    #[test]
319    fn test_logging_level_none() {
320        let logger = Apollo { logging_level: Levels::NONE };
321        assert!(logger.debug("This is a test debug message").is_none());
322        assert!(logger.info("This is a test info message").is_none());
323        assert!(logger.warn("This is a test warning message").is_none());
324        assert!(logger.error("This is a test error message").is_none());
325        assert!(logger.critical("This is a test critical message").is_none());
326    }
327    
328    #[test]
329    fn test_default_creates_new_instance() {
330        let logger = Apollo::default();
331        
332        assert!(logger.debug("This is a test debug message").is_some());
333    }
334}