acta 0.0.1

A customizable logging library for Rust
Documentation
use std::path::Path;

#[cfg(feature = "compress")]
use std::io::Write;

use crate::config::LogRotation;

pub fn rotate_log_file(path: &Path, mode: LogRotation) -> crate::error::Result<()> {
    if !path.exists() {
        return Ok(());
    }

    match mode {
        LogRotation::None => Ok(()),
        LogRotation::Rename => {
            let renamed = path.with_extension(format!("{}.log", now_timestamp()));
            std::fs::rename(path, renamed)?;
            Ok(())
        }
        #[cfg(feature = "compress")]
        LogRotation::Compress => {
            let gz_path = path.with_extension(format!("{}.log.gz", now_timestamp()));
            let input = std::fs::read(path)?;
            let output = std::fs::File::create(&gz_path)?;
            let mut encoder = flate2::write::GzEncoder::new(output, flate2::Compression::default());
            encoder.write_all(&input)?;
            encoder.finish()?;
            std::fs::remove_file(path)?;
            Ok(())
        }
    }
}

fn now_timestamp() -> String {
    chrono::Local::now().format("%Y-%m-%d_%H-%M-%S").to_string()
}

#[cfg(feature = "file")]
pub(crate) fn resolve_log_path(path: &Path) -> std::path::PathBuf {
    match std::fs::OpenOptions::new()
        .create(true)
        .append(true)
        .open(path)
    {
        Ok(_) => path.to_path_buf(),
        Err(_) => {
            let pid = std::process::id();
            let stem = path
                .file_stem()
                .and_then(|s| s.to_str())
                .unwrap_or("latest");
            let ext = path.extension().and_then(|s| s.to_str()).unwrap_or("log");
            path.with_file_name(format!("{stem}-{pid}.{ext}"))
        }
    }
}