use crate::format::{Formatter, Record};
pub trait Dispatcher: Send + Sync {
fn dispatch(&self, record: &Record);
}
pub struct StdoutDispatcher<F: Formatter> {
formatter: F,
}
impl<F: Formatter> StdoutDispatcher<F> {
pub fn new(formatter: F) -> Self {
Self { formatter }
}
}
impl<F: Formatter + Send + Sync> Dispatcher for StdoutDispatcher<F> {
fn dispatch(&self, record: &Record) {
let output = self.formatter.format(record);
println!("{}", output);
}
}
pub struct StderrDispatcher<F: Formatter> {
formatter: F,
}
impl<F: Formatter> StderrDispatcher<F> {
pub fn new(formatter: F) -> Self {
Self { formatter }
}
}
impl<F: Formatter + Send + Sync> Dispatcher for StderrDispatcher<F> {
fn dispatch(&self, record: &Record) {
let output = self.formatter.format(record);
eprintln!("{}", output); }
}
#[cfg(test)]
mod tests {
use super::*;
use crate::format::JsonFormatter;
use crate::Level;
#[test]
fn test_stdout_dispatcher_execution() {
let args = format_args!("Testing stdout dispatcher");
let record = Record {
level: Level::Info,
args,
};
let dispatcher = StdoutDispatcher::new(JsonFormatter);
dispatcher.dispatch(&record);
}
#[test]
fn test_stderr_dispatcher_execution() {
let args = format_args!("Testing stderr dispatcher");
let record = Record {
level: Level::Error,
args,
};
let dispatcher = StderrDispatcher::new(JsonFormatter);
dispatcher.dispatch(&record);
}
}