tetanes 0.14.0

A cross-platform NES Emulator written in Rust using wgpu
use anyhow::Context;
use std::path::PathBuf;
use tracing_appender::{
    non_blocking::{NonBlockingBuilder, WorkerGuard},
    rolling::{RollingFileAppender, Rotation},
};
use tracing_subscriber::{
    fmt, layer::SubscriberExt, registry::LookupSpan, util::SubscriberInitExt,
};

#[must_use]
pub struct Log {
    _guard: WorkerGuard,
}

pub fn init_impl<S>(registry: S) -> anyhow::Result<(impl SubscriberInitExt, Log)>
where
    S: SubscriberExt + for<'a> LookupSpan<'a> + Sync + Send,
{
    let file_appender = RollingFileAppender::builder()
        .rotation(Rotation::DAILY)
        .max_log_files(3)
        .filename_prefix("tetanes")
        .filename_suffix("log")
        .build(
            dirs::data_local_dir()
                .map(|dir| dir.join("tetanes/logs"))
                .unwrap_or_else(|| PathBuf::from("logs")),
        )
        .context("failed to create log file")?;
    let (file_writer, guard) = NonBlockingBuilder::default()
        .buffered_lines_limit(4096)
        .thread_name("tetanes-logger")
        .finish(file_appender);

    let registry = registry
        .with(
            fmt::layer()
                .compact()
                .with_line_number(true)
                .with_thread_ids(true)
                .with_thread_names(true)
                .with_writer(file_writer),
        )
        .with(
            fmt::layer()
                .compact()
                .with_line_number(true)
                .with_thread_ids(true)
                .with_thread_names(true)
                .with_writer(std::io::stderr),
        );

    Ok((registry, Log { _guard: guard }))
}