use super::Sink;
use crate::formatter::Format;
use log::Record;
use std::io::Write;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ConsoleTarget {
Stdout,
Stderr,
#[default]
Mixed,
}
#[derive(Debug)]
pub struct ConsoleSink {
target: ConsoleTarget,
}
impl ConsoleSink {
pub fn new(target: ConsoleTarget) -> Self {
Self { target }
}
pub fn stdout() -> Self {
Self::new(ConsoleTarget::Stdout)
}
pub fn stderr() -> Self {
Self::new(ConsoleTarget::Stderr)
}
pub fn mixed() -> Self {
Self::new(ConsoleTarget::Mixed)
}
}
impl Default for ConsoleSink {
fn default() -> Self {
Self::mixed()
}
}
impl Sink for ConsoleSink {
fn write(&self, record: &Record, formatter: &dyn Format) {
let formatted = formatter.format(record);
let use_stderr = match self.target {
ConsoleTarget::Stdout => false,
ConsoleTarget::Stderr => true,
ConsoleTarget::Mixed => matches!(record.level(), log::Level::Error | log::Level::Warn),
};
if use_stderr {
let _ = std::io::stderr().write_all(formatted.as_bytes());
} else {
let _ = std::io::stdout().write_all(formatted.as_bytes());
}
}
fn flush(&self) {
let _ = std::io::stdout().flush();
let _ = std::io::stderr().flush();
}
}