ani-cli-rs 0.11.1

Cross-platform Rust port of ani-cli with Anikoto providers and a reusable provider/playback library
Documentation
use std::{fs::OpenOptions, io::Write, path::PathBuf};

use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt, util::SubscriberInitExt};

fn log_file_path() -> PathBuf {
    if let Ok(path) = std::env::var("ANI_CLI_LOG_PATH") {
        return PathBuf::from(path);
    }

    std::env::current_dir()
        .unwrap_or_else(|_| std::env::temp_dir())
        .join("ani-cli-rs.log")
}

pub fn init() {
    let filter = EnvFilter::from_default_env();
    let log_path = log_file_path();

    if let Some(parent) = log_path.parent() {
        let _ = std::fs::create_dir_all(parent);
    }

    let file = OpenOptions::new().create(true).append(true).open(&log_path);

    match file {
        Ok(mut file) => {
            let _ = file.write_all(b"\n=== ani-cli-rs log started ===\n");
            let _ = file.flush();

            tracing_subscriber::registry()
                .with(
                    tracing_subscriber::fmt::layer()
                        .with_target(false)
                        .compact()
                        .with_writer(std::io::stderr)
                        .with_ansi(true)
                        .with_filter(filter.clone()),
                )
                .with(
                    tracing_subscriber::fmt::layer()
                        .with_target(false)
                        .compact()
                        .with_writer(file)
                        .with_ansi(false)
                        .with_filter(filter),
                )
                .init();
        }
        Err(error) => {
            eprintln!("Failed to open log file {}: {error}", log_path.display());
            tracing_subscriber::fmt()
                .with_target(false)
                .compact()
                .with_env_filter(filter)
                .init();
        }
    }
}

#[cfg(test)]
mod tests {
    use std::{env, path::PathBuf};

    use super::log_file_path;

    #[test]
    fn log_file_path_respects_env_override() {
        let override_path = PathBuf::from("/tmp/ani-cli-rs-custom.log");
        unsafe {
            env::set_var("ANI_CLI_LOG_PATH", &override_path);
        }

        let resolved = log_file_path();

        unsafe {
            env::remove_var("ANI_CLI_LOG_PATH");
        }
        assert_eq!(resolved, override_path);
    }
}