pub struct Log;
pub struct ChannelLog {
channel: String,
}
impl Log {
pub fn channel(channel: impl Into<String>) -> ChannelLog {
ChannelLog {
channel: channel.into(),
}
}
pub fn debug(message: impl AsRef<str>) {
let message = message.as_ref();
crate::write_to_handler(&crate::format_log_line("DEBUG", message));
}
pub fn info(message: impl AsRef<str>) {
let message = message.as_ref();
crate::write_to_handler(&crate::format_log_line("INFO", message));
}
pub fn warn(message: impl AsRef<str>) {
let message = message.as_ref();
crate::write_to_handler(&crate::format_log_line("WARN", message));
}
pub fn error(message: impl AsRef<str>) {
let message = message.as_ref();
crate::write_to_handler(&crate::format_log_line("ERROR", message));
}
}
impl ChannelLog {
pub fn debug(&self, message: impl AsRef<str>) {
let message = message.as_ref();
crate::write_to_channel_or_handler(
&self.channel,
&crate::format_log_line("DEBUG", message),
);
}
pub fn info(&self, message: impl AsRef<str>) {
let message = message.as_ref();
crate::write_to_channel_or_handler(&self.channel, &crate::format_log_line("INFO", message));
}
pub fn warn(&self, message: impl AsRef<str>) {
let message = message.as_ref();
crate::write_to_channel_or_handler(&self.channel, &crate::format_log_line("WARN", message));
}
pub fn error(&self, message: impl AsRef<str>) {
let message = message.as_ref();
crate::write_to_channel_or_handler(
&self.channel,
&crate::format_log_line("ERROR", message),
);
}
}
#[cfg(test)]
mod tests {
use std::io;
use std::sync::{Arc, Mutex};
use std::time::{SystemTime, UNIX_EPOCH};
use crate::handlers::Handler;
use crate::{set_channel_handler, Log};
struct Capture {
lines: Arc<Mutex<Vec<String>>>,
}
impl Handler for Capture {
fn log(&self, message: &str) -> io::Result<()> {
self.lines
.lock()
.expect("capture lock should not be poisoned")
.push(message.to_string());
Ok(())
}
}
#[test]
fn writes_to_named_channel() {
let stamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("system time should be after unix epoch")
.as_nanos();
let channel = format!("channel-{stamp}");
let lines = Arc::new(Mutex::new(Vec::new()));
set_channel_handler(
channel.clone(),
Arc::new(Capture {
lines: Arc::clone(&lines),
}),
);
Log::channel(channel).info("named message");
let lines = lines.lock().expect("capture lock should not be poisoned");
assert_eq!(lines.len(), 1);
assert!(lines[0].contains("INFO"));
assert!(lines[0].contains("named message"));
}
}