dlog/
dlog.rs

1use dev_utils::{__delay_ms, app_dt, datetime::*, dlog::*, format::*};
2
3fn main() {
4    app_dt!(file!());
5
6    println!(
7        "{}",
8        "--- dlog Showcase ---".style(Style::Bold).color(CYAN)
9    );
10
11    // Initialize logging
12    set_max_level(Level::Trace);
13
14    // showcase_log_levels();
15    // showcase_log_use_cases(); // * gen some delay's to simulate real-world scenarios
16    // showcase_log_formatting();
17    // showcase_datetime_features(); // Not very awesome... .__.
18    showcase_log_performance();  // = 352.6482ms / 10000 logs (average of 10 runs)
19}
20
21fn showcase_log_levels() {
22    println!(
23        "\n{}",
24        "Log Levels Demonstration:"
25            .style(Style::Bold)
26            .style(Style::Italic)
27    );
28
29    // Helper function to set log level, print color-coded messages, and log all levels
30    fn demonstrate_log_level(level: Level, color: Color, description: &str) {
31        println!(
32            "\n{}",
33            format!("Log Level: {}", description)
34                .style(Style::Bold)
35                .color(color)
36        );
37        set_max_level(level);
38        log_all_levels();
39    }
40
41    // Function to log messages at all levels
42    fn log_all_levels() {
43        trace!("Most detailed level, useful for step-by-step debugging");
44        debug!("Useful for diagnosing issues");
45        info!("General operational messages about program execution");
46        warn!("Something unexpected happened, but the program can still continue");
47        error!("A serious problem occurred, indicating potential a failure");
48    }
49
50    // Demonstrate log levels with different settings
51    demonstrate_log_level(
52        Level::Trace,
53        Color::new(180, 0, 158),
54        "Trace (all levels visible)",
55    );
56    demonstrate_log_level(
57        Level::Debug,
58        Color::new(97, 214, 214),
59        "Debug (Trace hidden, Debug and above visible)",
60    );
61    demonstrate_log_level(
62        Level::Info,
63        Color::new(22, 198, 12),
64        "Info (Trace and Debug hidden, Info and above visible)",
65    );
66    demonstrate_log_level(
67        Level::Warn,
68        Color::new(245, 245, 57),
69        "Warn (Only Warn and Error visible)",
70    );
71    demonstrate_log_level(
72        Level::Error,
73        Color::new(231, 72, 86),
74        "Error (Only Error logs visible)",
75    );
76
77    // Restore Trace level at the end
78    set_max_level(Level::Trace);
79    println!(
80        "\n{}",
81        "Log Level restored to Trace."
82            .style(Style::Bold)
83            .color(GREEN)
84    );
85}
86
87fn showcase_log_formatting() {
88    println!(
89        "\n{}",
90        "Enhanced Log Formatting Features:"
91            .style(Style::Bold)
92            .style(Style::Italic)
93    );
94
95    info!("Standard log message");
96
97    // Multi-line log for a simulated data structure
98    let user_data = vec![
99        ("UserID", "12345"),
100        ("Username", "johndoe"),
101        ("Email", "johndoe@example.com"),
102        ("Role", "Admin"),
103    ];
104
105    debug!(
106        "Logging multi-line structured data:\n{}",
107        user_data
108            .iter()
109            .map(|(key, value)| format!("\t{}: {}", key, value))
110            .collect::<Vec<_>>()
111            .join("\n")
112    );
113
114    // Log a long message split across multiple lines
115    info!(
116        "This is a long log message that spans multiple lines for better readability. \
117        It demonstrates how long strings or messages can be split into readable chunks \
118        without breaking the content flow."
119    );
120
121    // Log with colored and styled text
122    let formatted_text = "Formatted".style(Style::Bold).color(GREEN);
123    info!(
124        "Logs can include {} and {} text",
125        formatted_text,
126        "styled".style(Style::Italic).color(MAGENTA)
127    );
128
129    // Log the current timestamp
130    let now = DateTime::now();
131    info!("Current timestamp: {}", now);
132
133    // todo: Add full compatibility with thie multiline log
134    let err_dt = vec![
135        ("Code", "404"),
136        ("Message", "Resource not found"),
137        ("File", file!()),
138    ];
139    // iter over all the data on err_dt and apply the dim style to all the values
140    let err_dt = err_dt
141        .iter()
142        .map(|(key, value)| (key, value.style(Style::Dim)))
143        .collect::<Vec<_>>();
144
145    // Multi-line error simulation
146    error!(
147        "Error on line: {}\n{}",
148        line!(),
149        err_dt
150            .iter()
151            .map(|(key, value)| format!("\t{}: {}", key, value))
152            .collect::<Vec<_>>()
153            .join("\n")
154    );
155
156    // todo: FIX THE ERRORS OCURRED WHEN HANDLING THE MULTILINE LOG...
157    // todo: IT ALSO HAVE SOME ERROR IN WHICH THE STYLE IS APPLIED TO THE WHOLE STRING...
158    // ^ In this case, the "Some new data:" is being styled as a whole string,
159    // ^ not just the "Code: 200" and "Message: You got some successulf penchs"...
160    // same as above but using the str in plain text
161    info!(
162        "Some new data:\n{}{}{}", // Added {} for the file part
163        format!("\tCode: {}\n", "200".style(Style::Underline)), // Style only "200"
164        format!("\tMessage: {}\n\t", "You got some successulf penchs".style(Style::Underline)), // Style only the message
165        file!().style(Style::Bold)
166    );
167}
168
169// = Time to log 10000 messages: 352.6482ms
170// = Average time per log: 35.264µs
171fn showcase_log_performance() {
172    println!(
173        "\n{}",
174        "Log Performance:".style(Style::Bold).style(Style::Italic)
175    );
176
177    let iterations = 10000;
178    let start = std::time::Instant::now();
179
180    (0..iterations).for_each(|i| trace!("Performance test log {}", i));
181
182    let duration = start.elapsed();
183    println!("Time to log {} messages: {:?}", iterations, duration);
184    println!("Average time per log: {:?}", duration / iterations as u32);
185}
186
187fn showcase_log_use_cases() {
188    println!(
189        "\n{}",
190        "Practical Use Cases:"
191            .style(Style::Bold)
192            .style(Style::Italic)
193    );
194
195    // Simulating an application startup
196    info!("Application starting up...");
197    debug!("Initializing modules...");
198    __delay_ms(500);
199    info!("Database connection established");
200    __delay_ms(300);
201    // warn!("Config file not found, using default settings");
202    __delay_ms(200);
203    error!("Failed to load user preferences");
204    info!("Application startup complete");
205
206    // Simulating a function call
207    debug!("Entering function process_data()");
208    __delay_ms(100);
209    trace!("Processing item 1 of 3");
210    __delay_ms(50);
211    trace!("Processing item 2 of 3");
212    __delay_ms(50);
213    trace!("Processing item 3 of 3");
214    __delay_ms(100);
215    debug!("Exiting function process_data()");
216
217    info!("Data processing completed successfully");
218
219    // same as above but now use a tuple to store the macro type, message, and delay, then iterate over it
220
221    // logs.iter().for_each(|(log, msg, delay)| {
222    //     log!("{}", msg);
223    //     __delay_ms(*delay);
224    // });
225}
226
227fn showcase_datetime_features() {
228    println!(
229        "\n{}",
230        "DateTime Features:".style(Style::Bold).style(Style::Italic)
231    );
232
233    // Creating a DateTime instance
234    let now = DateTime::now();
235    info!("Current date and time: {}", now);
236
237    // Creating a custom DateTime
238    let custom_date = Date::new(2023, 12, 31).unwrap();
239    let custom_time = Time::new(23, 59, 59).unwrap();
240    let custom_datetime = DateTime {
241        date: custom_date,
242        time: custom_time,
243    };
244    info!("Custom DateTime: {}", custom_datetime);
245
246    // Parsing a DateTime from a string
247    let parsed_datetime: DateTime = "2023-05-01 12:34:56".parse().unwrap();
248    info!("Parsed DateTime: {}", parsed_datetime);
249
250    // DateTime from timestamp
251    let from_timestamp = DateTime::from_timestamp(1682899200).unwrap();
252    info!("DateTime from timestamp: {}", from_timestamp);
253
254    // Demonstrating error handling
255    match Date::new(2023, 2, 29) {
256        // 29th Feb 2023 (not a leap year)
257        Ok(date) => info!("Valid date: {:?}", date),
258        Err(e) => println!("Invalid date: {}", e),
259        // Err(e) => warn!("Invalid date: {}", e),
260    }
261
262    // Comparing DateTimes
263    info!(
264        "Comparing DateTimes: {} is earlier than {}",
265        "2023-05-01 12:00:00".parse::<DateTime>().unwrap(),
266        "2023-05-01 13:00:00".parse::<DateTime>().unwrap(),
267    );
268
269    // Demonstrating leap year
270    let leap_year = 2024;
271    info!(
272        "Is {} a leap year? {}",
273        leap_year,
274        Date::is_leap_year(leap_year)
275    );
276}