shortener 0.1.1

A simple URL shortener.
Documentation
use std::fs::{File, OpenOptions};
use std::io::{self, Write};
use std::sync::Mutex;

use chrono::Local;
use log::{LevelFilter, Log, Metadata, Record};

pub struct Logger {
  file: Mutex<File>,
}

impl Logger {
  pub fn init(path: &str) -> io::Result<()> {
    let mut options = OpenOptions::new();
    options.create(true).append(true).write(true);

    #[cfg(unix)]
    {
      use std::os::unix::fs::OpenOptionsExt;
      options.mode(0o600);
    }

    let logger = Box::new(Self {
      file: Mutex::new(options.open(path)?),
    });
    log::set_boxed_logger(logger)
      .map(|()| log::set_max_level(LevelFilter::Info))
      .map_err(io::Error::other)
  }
}

impl Log for Logger {
  fn enabled(&self, _metadata: &Metadata) -> bool {
    true
  }

  fn log(&self, record: &Record) {
    let line = format!("[{}] {}", timestamp(), record.args());
    println!("{}", line);
    if let Ok(mut file) = self.file.lock() {
      let _ = writeln!(file, "{}", line);
    }
  }

  fn flush(&self) {}
}

fn timestamp() -> String {
  Local::now().format("%Y-%m-%d %H:%M:%S%.6f").to_string()
}