use super::define::*;
pub trait Target: AnyTarget + Send + Sync + 'static {
fn write(&self, buf: &[u8]);
}
pub trait AnyTarget: Any {
fn as_any(&self) -> &dyn Any;
}
impl<T: Any> AnyTarget for T {
#[inline]
fn as_any(&self) -> &dyn Any {
self
}
}
pub struct StdoutTarget;
impl Target for StdoutTarget {
#[inline]
fn write(&self, buf: &[u8]) {
let _ = std::io::stdout().write_all(buf);
}
}
pub struct StderrTarget;
impl Target for StderrTarget {
#[inline]
fn write(&self, buf: &[u8]) {
let _ = std::io::stderr().write_all(buf);
}
}
pub struct FileTarget {
pub file: Mutex<std::fs::File>,
}
impl FileTarget {
pub fn new(path: impl AsRef<Path>) -> std::io::Result<Self> {
if let Some(dir) = path.as_ref().parent() {
std::fs::create_dir_all(dir)?;
}
Ok(Self {file: Mutex::new(std::fs::OpenOptions::new().create(true).append(true).open(path)?)})
}
}
impl Target for FileTarget {
#[inline]
fn write(&self, buf: &[u8]) {
match self.file.lock() {
Ok(mut obj) => match obj.write_all(buf) {
Ok(_) => {}
Err(err) => { eprintln!("Error: {}", err); }
}
Err(err) => { eprintln!("Error: {}", err); }
};
}
}