1pub struct Log;
2pub struct ChannelLog {
3 channel: String,
4}
5
6impl Log {
7 pub fn channel(channel: impl Into<String>) -> ChannelLog {
8 ChannelLog {
9 channel: channel.into(),
10 }
11 }
12
13 pub fn debug(message: impl AsRef<str>) {
14 let message = message.as_ref();
15 crate::write_to_handler(&crate::format_log_line("DEBUG", message));
16 }
17
18 pub fn info(message: impl AsRef<str>) {
19 let message = message.as_ref();
20 crate::write_to_handler(&crate::format_log_line("INFO", message));
21 }
22
23 pub fn warn(message: impl AsRef<str>) {
24 let message = message.as_ref();
25 crate::write_to_handler(&crate::format_log_line("WARN", message));
26 }
27
28 pub fn error(message: impl AsRef<str>) {
29 let message = message.as_ref();
30 crate::write_to_handler(&crate::format_log_line("ERROR", message));
31 }
32}
33
34impl ChannelLog {
35 pub fn debug(&self, message: impl AsRef<str>) {
36 let message = message.as_ref();
37 crate::write_to_channel_or_handler(
38 &self.channel,
39 &crate::format_log_line("DEBUG", message),
40 );
41 }
42
43 pub fn info(&self, message: impl AsRef<str>) {
44 let message = message.as_ref();
45 crate::write_to_channel_or_handler(&self.channel, &crate::format_log_line("INFO", message));
46 }
47
48 pub fn warn(&self, message: impl AsRef<str>) {
49 let message = message.as_ref();
50 crate::write_to_channel_or_handler(&self.channel, &crate::format_log_line("WARN", message));
51 }
52
53 pub fn error(&self, message: impl AsRef<str>) {
54 let message = message.as_ref();
55 crate::write_to_channel_or_handler(
56 &self.channel,
57 &crate::format_log_line("ERROR", message),
58 );
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use std::io;
65 use std::sync::{Arc, Mutex};
66 use std::time::{SystemTime, UNIX_EPOCH};
67
68 use crate::handlers::Handler;
69 use crate::{set_channel_handler, Log};
70
71 struct Capture {
72 lines: Arc<Mutex<Vec<String>>>,
73 }
74
75 impl Handler for Capture {
76 fn log(&self, message: &str) -> io::Result<()> {
77 self.lines
78 .lock()
79 .expect("capture lock should not be poisoned")
80 .push(message.to_string());
81 Ok(())
82 }
83 }
84
85 #[test]
86 fn writes_to_named_channel() {
87 let stamp = SystemTime::now()
88 .duration_since(UNIX_EPOCH)
89 .expect("system time should be after unix epoch")
90 .as_nanos();
91 let channel = format!("channel-{stamp}");
92 let lines = Arc::new(Mutex::new(Vec::new()));
93
94 set_channel_handler(
95 channel.clone(),
96 Arc::new(Capture {
97 lines: Arc::clone(&lines),
98 }),
99 );
100
101 Log::channel(channel).info("named message");
102
103 let lines = lines.lock().expect("capture lock should not be poisoned");
104 assert_eq!(lines.len(), 1);
105 assert!(lines[0].contains("INFO"));
106 assert!(lines[0].contains("named message"));
107 }
108}