dlog/
dlog.rs

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