nonblocking_logger/
macros.rs

1/// Macros for convenient logging with string formatting support
2///
3/// These macros provide a convenient way to log messages with format string support,
4/// similar to the standard library's `println!` macro family.
5///
6/// # Examples
7///
8/// ```rust
9/// use nonblocking_logger::{info, debug, error};
10///
11/// fn main() {
12///     let user_id = 42;
13///     let status = "active";
14///     
15///     // Simple string
16///     info!("User logged in");
17///     
18///     // With formatting
19///     info!("User {} has status: {}", user_id, status);
20///     
21///     // With debug formatting
22///     debug!("Debug info: {:?}", vec![1, 2, 3]);
23///     
24///     // Error with formatting
25///     error!("Failed to process user {}: {}", user_id, "connection timeout");
26/// }
27/// ```
28
29/// Log a message using format string syntax (always outputs, no level filtering)
30///
31/// # Examples
32///
33/// ```rust
34/// use nonblocking_logger::log;
35///
36/// fn main() {
37///     let count = 5;
38///     
39///     // Using global logger
40///     log!("Processing {} items", count);
41/// }
42/// ```
43#[macro_export]
44macro_rules! log {
45    ($($arg:tt)+) => {
46        { let _ = $crate::log(&format!($($arg)+)); }
47    };
48}
49
50/// Log a message with a specific logger using format string syntax (always outputs, no level filtering)
51///
52/// # Examples
53///
54/// ```rust
55/// use nonblocking_logger::{log_with, Logger};
56///
57/// fn main() {
58///     let count = 5;
59///     let logger = Logger::new().stdout();
60///     
61///     // Using specific logger
62///     log_with!(logger, "Processing {} items", count);
63/// }
64/// ```
65#[macro_export]
66macro_rules! log_with {
67    ($logger:expr, $($arg:tt)+) => {
68        { let _ = $logger.log(&format!($($arg)+)); }
69    };
70}
71
72/// Log an error message using format string syntax
73///
74/// # Examples
75///
76/// ```rust
77/// use nonblocking_logger::{error, error_with, Logger};
78///
79/// fn main() {
80///     let error_code = 500;
81///     
82///     // Using global logger
83///     error!("Server error: {}", error_code);
84///     
85///     // Using specific logger
86///     let logger = Logger::new().stdout();
87///     error_with!(logger, "Server error: {}", error_code);
88/// }
89/// ```
90#[macro_export]
91macro_rules! error {
92    ($($arg:tt)+) => {
93        { let _ = $crate::error(&format!($($arg)+)); }
94    };
95}
96
97/// Log an error message using format string syntax with a specific logger
98#[macro_export]
99macro_rules! error_with {
100    ($logger:expr, $($arg:tt)+) => {
101        { let _ = $logger.error(&format!($($arg)+)); }
102    };
103}
104
105/// Log a warning message using format string syntax
106///
107/// # Examples
108///
109/// ```rust
110/// use nonblocking_logger::{warning, warning_with, Logger};
111///
112/// fn main() {
113///     let threshold = 80;
114///     
115///     // Using global logger
116///     warning!("CPU usage is {}%", threshold);
117///     
118///     // Using specific logger
119///     let logger = Logger::new().stdout();
120///     warning_with!(logger, "CPU usage is {}%", threshold);
121/// }
122/// ```
123#[macro_export]
124macro_rules! warning {
125    ($($arg:tt)+) => {
126        { let _ = $crate::warning(&format!($($arg)+)); }
127    };
128}
129
130/// Log a warning message using format string syntax with a specific logger
131#[macro_export]
132macro_rules! warning_with {
133    ($logger:expr, $($arg:tt)+) => {
134        { let _ = $logger.warning(&format!($($arg)+)); }
135    };
136}
137
138/// Log an info message using format string syntax
139///
140/// # Examples
141///
142/// ```rust
143/// use nonblocking_logger::{info, info_with, Logger};
144///
145/// fn main() {
146///     let user = "alice";
147///     
148///     // Using global logger
149///     info!("User {} connected", user);
150///     
151///     // Using specific logger
152///     let logger = Logger::new().stdout();
153///     info_with!(logger, "User {} connected", user);
154/// }
155/// ```
156#[macro_export]
157macro_rules! info {
158    ($($arg:tt)+) => {
159        { let _ = $crate::info(&format!($($arg)+)); }
160    };
161}
162
163/// Log an info message using format string syntax with a specific logger
164#[macro_export]
165macro_rules! info_with {
166    ($logger:expr, $($arg:tt)+) => {
167        { let _ = $logger.info(&format!($($arg)+)); }
168    };
169}
170
171/// Log a debug message using format string syntax
172///
173/// # Examples
174///
175/// ```rust
176/// use nonblocking_logger::{debug, debug_with, Logger};
177///
178/// fn main() {
179///     let data = vec![1, 2, 3];
180///     
181///     // Using global logger
182///     debug!("Processing data: {:?}", data);
183///     
184///     // Using specific logger
185///     let logger = Logger::new().stdout();
186///     debug_with!(logger, "Processing data: {:?}", data);
187/// }
188/// ```
189#[macro_export]
190macro_rules! debug {
191    ($($arg:tt)+) => {
192        { let _ = $crate::debug(&format!($($arg)+)); }
193    };
194}
195
196/// Log a debug message using format string syntax with a specific logger
197#[macro_export]
198macro_rules! debug_with {
199    ($logger:expr, $($arg:tt)+) => {
200        { let _ = $logger.debug(&format!($($arg)+)); }
201    };
202}
203
204/// Log a trace message using format string syntax
205///
206/// # Examples
207///
208/// ```rust
209/// use nonblocking_logger::{trace, trace_with, Logger};
210///
211/// fn main() {
212///     let step = "validation";
213///     
214///     // Using global logger
215///     trace!("Entering {} step", step);
216///     
217///     // Using specific logger
218///     let logger = Logger::new().stdout();
219///     trace_with!(logger, "Entering {} step", step);
220/// }
221/// ```
222#[macro_export]
223macro_rules! trace {
224    ($($arg:tt)+) => {
225        { let _ = $crate::trace(&format!($($arg)+)); }
226    };
227}
228
229/// Log a trace message using format string syntax with a specific logger
230#[macro_export]
231macro_rules! trace_with {
232    ($logger:expr, $($arg:tt)+) => {
233        { let _ = $logger.trace(&format!($($arg)+)); }
234    };
235}
236
237/// Log a message with lazy evaluation using format string syntax
238///
239/// The closure is only executed if the log level is sufficient.
240///
241/// # Examples
242///
243/// ```rust
244/// use nonblocking_logger::{log_lazy, log_lazy_with, Logger};
245///
246/// fn expensive_computation() -> String {
247///     // Some expensive operation
248///     "result".to_string()
249/// }
250///
251/// fn main() {
252///     let user_id = 42;
253///     
254///     // Using global logger
255///     log_lazy!(|| "User {}: {}", user_id, expensive_computation());
256///     
257///     // Using specific logger
258///     let logger = Logger::new().stdout();
259///     log_lazy_with!(logger, || "User {}: {}", user_id, expensive_computation());
260/// }
261/// ```
262#[macro_export]
263macro_rules! log_lazy {
264    (|| $($arg:tt)+) => {
265        { let _ = $crate::log_lazy(|| format!($($arg)+)); }
266    };
267}
268
269/// Log a message with lazy evaluation using format string syntax with a specific logger
270#[macro_export]
271macro_rules! log_lazy_with {
272    ($logger:expr, || $($arg:tt)+) => {
273        { let _ = $logger.log_lazy(|| format!($($arg)+)); }
274    };
275}
276
277/// Log an error message with lazy evaluation using format string syntax
278#[macro_export]
279macro_rules! error_lazy {
280    (|| $($arg:tt)+) => {
281        { let _ = $crate::error_lazy(|| format!($($arg)+)); }
282    };
283}
284
285/// Log an error message with lazy evaluation using format string syntax with a specific logger
286#[macro_export]
287macro_rules! error_lazy_with {
288    ($logger:expr, || $($arg:tt)+) => {
289        { let _ = $logger.error_lazy(|| format!($($arg)+)); }
290    };
291}
292
293/// Log a warning message with lazy evaluation using format string syntax
294#[macro_export]
295macro_rules! warning_lazy {
296    (|| $($arg:tt)+) => {
297        { let _ = $crate::warning_lazy(|| format!($($arg)+)); }
298    };
299}
300
301/// Log a warning message with lazy evaluation using format string syntax with a specific logger
302#[macro_export]
303macro_rules! warning_lazy_with {
304    ($logger:expr, || $($arg:tt)+) => {
305        { let _ = $logger.warning_lazy(|| format!($($arg)+)); }
306    };
307}
308
309/// Log an info message with lazy evaluation using format string syntax
310#[macro_export]
311macro_rules! info_lazy {
312    (|| $($arg:tt)+) => {
313        { let _ = $crate::info_lazy(|| format!($($arg)+)); }
314    };
315}
316
317/// Log an info message with lazy evaluation using format string syntax with a specific logger
318#[macro_export]
319macro_rules! info_lazy_with {
320    ($logger:expr, || $($arg:tt)+) => {
321        { let _ = $logger.info_lazy(|| format!($($arg)+)); }
322    };
323}
324
325/// Log a debug message with lazy evaluation using format string syntax
326#[macro_export]
327macro_rules! debug_lazy {
328    (|| $($arg:tt)+) => {
329        { let _ = $crate::debug_lazy(|| format!($($arg)+)); }
330    };
331}
332
333/// Log a debug message with lazy evaluation using format string syntax with a specific logger
334#[macro_export]
335macro_rules! debug_lazy_with {
336    ($logger:expr, || $($arg:tt)+) => {
337        { let _ = $logger.debug_lazy(|| format!($($arg)+)); }
338    };
339}
340
341/// Log a trace message with lazy evaluation using format string syntax
342#[macro_export]
343macro_rules! trace_lazy {
344    (|| $($arg:tt)+) => {
345        { let _ = $crate::trace_lazy(|| format!($($arg)+)); }
346    };
347}
348
349/// Log a trace message with lazy evaluation using format string syntax with a specific logger
350#[macro_export]
351macro_rules! trace_lazy_with {
352    ($logger:expr, || $($arg:tt)+) => {
353        { let _ = $logger.trace_lazy(|| format!($($arg)+)); }
354    };
355}
356
357#[cfg(test)]
358#[cfg(not(target_arch = "wasm32"))]
359mod tests {
360
361    #[test]
362    fn test_log_macro() {
363        let count = 5;
364        log!("Processing {} items", count);
365    }
366
367    #[test]
368    fn test_error_macro() {
369        let error_code = 500;
370        error!("Server error: {}", error_code);
371    }
372
373    #[test]
374    fn test_warning_macro() {
375        let threshold = 80;
376        warning!("CPU usage is {}%", threshold);
377    }
378
379    #[test]
380    fn test_info_macro() {
381        let user = "alice";
382        info!("User {} connected", user);
383    }
384
385    #[test]
386    fn test_debug_macro() {
387        let data = vec![1, 2, 3];
388        debug!("Processing data: {:?}", data);
389    }
390
391    #[test]
392    fn test_trace_macro() {
393        let step = "validation";
394        trace!("Entering {} step", step);
395    }
396
397    #[test]
398    fn test_log_lazy_macro() {
399        let user_id = 42;
400        log_lazy!(|| "User {}: {}", user_id, "result");
401    }
402
403    #[test]
404    fn test_error_lazy_macro() {
405        let error_code = 500;
406        error_lazy!(|| "Server error: {}", error_code);
407    }
408
409    #[test]
410    fn test_warning_lazy_macro() {
411        let threshold = 80;
412        warning_lazy!(|| "CPU usage is {}%", threshold);
413    }
414
415    #[test]
416    fn test_info_lazy_macro() {
417        let user = "alice";
418        info_lazy!(|| "User {} connected", user);
419    }
420
421    #[test]
422    fn test_debug_lazy_macro() {
423        let data = vec![1, 2, 3];
424        debug_lazy!(|| "Processing data: {:?}", data);
425    }
426
427    #[test]
428    fn test_trace_lazy_macro() {
429        let step = "validation";
430        trace_lazy!(|| "Entering {} step", step);
431    }
432
433    #[test]
434    fn test_macro_with_multiple_args() {
435        let user_id = 42;
436        let action = "login";
437        let timestamp = "2025-01-14 10:30:00";
438
439        info!("User {} performed {} at {}", user_id, action, timestamp);
440    }
441
442    #[test]
443    fn test_macro_with_debug_formatting() {
444        let data = vec![1, 2, 3, 4, 5];
445        let metadata = std::collections::HashMap::from([("key1", "value1"), ("key2", "value2")]);
446
447        debug!("Data: {:?}, Metadata: {:?}", data, metadata);
448    }
449
450    #[test]
451    fn test_macro_with_no_args() {
452        info!("Simple message without formatting");
453    }
454
455    #[test]
456    fn test_log_macro_with_logger() {
457        use crate::Logger;
458        let logger = Logger::new().stdout();
459        let count = 5;
460        log_with!(
461            logger,
462            "Processing {} items with custom logger",
463            count
464        );
465    }
466
467    #[test]
468    fn test_error_macro_with_logger() {
469        use crate::Logger;
470        let logger = Logger::new().stdout();
471        let error_code = 500;
472        error_with!(logger, "Server error with custom logger: {}", error_code);
473    }
474
475    #[test]
476    fn test_warning_macro_with_logger() {
477        use crate::Logger;
478        let logger = Logger::new().stdout();
479        let threshold = 80;
480        warning_with!(logger, "CPU usage with custom logger is {}%", threshold);
481    }
482
483    #[test]
484    fn test_info_macro_with_logger() {
485        use crate::Logger;
486        let logger = Logger::new().stdout();
487        let user = "alice";
488        info_with!(logger, "User {} connected with custom logger", user);
489    }
490
491    #[test]
492    fn test_debug_macro_with_logger() {
493        use crate::Logger;
494        let logger = Logger::new().stdout();
495        let data = vec![1, 2, 3];
496        debug_with!(logger, "Processing data with custom logger: {:?}", data);
497    }
498
499    #[test]
500    fn test_trace_macro_with_logger() {
501        use crate::Logger;
502        let logger = Logger::new().stdout();
503        let step = "validation";
504        trace_with!(logger, "Entering {} step with custom logger", step);
505    }
506
507    #[test]
508    fn test_log_lazy_macro_with_logger() {
509        use crate::Logger;
510        let logger = Logger::new().stdout();
511        let user_id = 42;
512        log_lazy_with!(
513            logger,
514            || "User {} with custom logger: {}",
515            user_id,
516            "result"
517        );
518    }
519
520    #[test]
521    fn test_error_lazy_macro_with_logger() {
522        use crate::Logger;
523        let logger = Logger::new().stdout();
524        let error_code = 500;
525        error_lazy_with!(logger, || "Server error with custom logger: {}", error_code);
526    }
527
528    #[test]
529    fn test_warning_lazy_macro_with_logger() {
530        use crate::Logger;
531        let logger = Logger::new().stdout();
532        let threshold = 80;
533        warning_lazy_with!(logger, || "CPU usage with custom logger is {}%", threshold);
534    }
535
536    #[test]
537    fn test_info_lazy_macro_with_logger() {
538        use crate::Logger;
539        let logger = Logger::new().stdout();
540        let user = "alice";
541        info_lazy_with!(logger, || "User {} connected with custom logger", user);
542    }
543
544    #[test]
545    fn test_debug_lazy_macro_with_logger() {
546        use crate::Logger;
547        let logger = Logger::new().stdout();
548        let data = vec![1, 2, 3];
549        debug_lazy_with!(logger, || "Processing data with custom logger: {:?}", data);
550    }
551
552    #[test]
553    fn test_trace_lazy_macro_with_logger() {
554        use crate::Logger;
555        let logger = Logger::new().stdout();
556        let step = "validation";
557        trace_lazy_with!(logger, || "Entering {} step with custom logger", step);
558    }
559
560    #[test]
561    fn test_macro_backward_compatibility() {
562        let count = 5;
563        log!(
564            "Backward compatibility test: {} items",
565            count
566        );
567        error!("Backward compatibility error test: {}", 500);
568        warning!("Backward compatibility warning test: {}%", 80);
569        info!("Backward compatibility info test: {}", "alice");
570        debug!("Backward compatibility debug test: {:?}", vec![1, 2, 3]);
571        trace!("Backward compatibility trace test: {}", "validation");
572    }
573}