use std::io::{self, Write};
use std::fs;
use std::sync::Mutex;
pub type Result = io::Result<()>;
pub trait Log: Send + Sync {
fn try_note(&self, message: &str) -> Result;
fn try_warning(&self, message: &str) -> Result;
fn try_error(&self, message: &str) -> Result;
#[allow(unused_must_use)]
#[inline]
fn note(&self, message: &str) {
self.try_note(message);
}
#[allow(unused_must_use)]
#[inline]
fn warning(&self, message: &str) {
self.try_warning(message);
}
#[allow(unused_must_use)]
#[inline]
fn error(&self, message: &str) {
self.try_error(message);
}
}
pub struct Quiet;
impl Log for Quiet {
fn try_note(&self, _message: &str) -> Result {
Ok(())
}
fn try_warning(&self, _message: &str) -> Result {
Ok(())
}
fn try_error(&self, _message: &str) -> Result {
Ok(())
}
}
pub struct StdOut;
impl Log for StdOut {
fn try_note(&self, message: &str) -> Result {
println!("note: {}", message);
Ok(())
}
fn try_warning(&self, message: &str) -> Result {
println!("warning: {}", message);
Ok(())
}
fn try_error(&self, message: &str) -> Result {
println!("error: {}", message);
Ok(())
}
}
pub struct File {
file: Mutex<fs::File>
}
impl File {
pub fn new(file: fs::File) -> File {
File {
file: Mutex::new(file)
}
}
}
impl Log for File {
fn try_note(&self, message: &str) -> Result {
let mut f = match self.file.lock() {
Ok(f) => f,
Err(_e) => return Err(io::Error::new(io::ErrorKind::Other, "poisoned log file lock"))
};
write!(f, "note: {}", message)
}
fn try_warning(&self, message: &str) -> Result {
let mut f = match self.file.lock() {
Ok(f) => f,
Err(_e) => return Err(io::Error::new(io::ErrorKind::Other, "poisoned log file lock"))
};
write!(f, "warning: {}", message)
}
fn try_error(&self, message: &str) -> Result {
let mut f = match self.file.lock() {
Ok(f) => f,
Err(_e) => return Err(io::Error::new(io::ErrorKind::Other, "poisoned log file lock"))
};
write!(f, "error: {}", message)
}
}
#[cfg(test)]
mod test {
use std::fs;
use log;
use Server;
use Context;
use Response;
use tempdir;
#[test]
fn log_to_file() {
let dir = tempdir::TempDir::new("log_to_file").unwrap();
let file = fs::File::create(&dir.path().join("test.log")).unwrap();
Server {
log: Box::new(log::File::new(file)),
..Server::new(|_: Context, _: Response| {})
}.build();
}
}