fb2-clean 0.5.1

A simple GUI/CLI utility to remove images from fb2 books.
Documentation
use log::{Level, LevelFilter, Log, Metadata, Record};
use std::{
    env,
    io::{self, IsTerminal, Write, stderr, stdout},
    sync::LazyLock,
};

static CLI_LOGGER: CliLogger = CliLogger;
pub struct CliLogger;

static STDOUT_ON_COLOR: LazyLock<bool> =
    LazyLock::new(|| should_enable_color(stdout().is_terminal()));
static STDERR_ON_COLOR: LazyLock<bool> =
    LazyLock::new(|| should_enable_color(stderr().is_terminal()));

impl CliLogger {
    pub fn init() {
        log::set_logger(&CLI_LOGGER).unwrap();
        log::set_max_level(LevelFilter::Info);
    }

    fn prf_prefix(level: Level) -> &'static str {
        match level {
            Level::Error if *STDERR_ON_COLOR => "\x1b[31m",
            Level::Error => "",
            Level::Warn if *STDERR_ON_COLOR => "\x1b[33m",
            Level::Warn => "",
            Level::Debug if *STDOUT_ON_COLOR => "\x1b[34m",
            Level::Debug => "",
            Level::Trace if *STDOUT_ON_COLOR => "\x1b[35m",
            Level::Trace => "",
            _ => "",
        }
    }

    fn prf_suffix(level: Level) -> &'static str {
        match level {
            Level::Error | Level::Warn if *STDERR_ON_COLOR => "\x1b[0m: ",
            Level::Error | Level::Warn => ": ",
            Level::Debug | Level::Trace if *STDOUT_ON_COLOR => "\x1b[0m: ",
            Level::Debug | Level::Trace => ": ",
            _ => "",
        }
    }
}

impl Log for CliLogger {
    fn enabled(&self, metadata: &Metadata) -> bool {
        metadata.target().starts_with("fb2_clean")
    }

    fn log(&self, record: &Record) {
        if !self.enabled(record.metadata()) {
            return;
        }

        let level = record.level();

        let msg = format!(
            "{}{}{}{}\n",
            Self::prf_prefix(level),
            crate::log_prefix_root(level),
            Self::prf_suffix(level),
            record.args()
        );
        let msg = msg.as_bytes();

        match level {
            Level::Error | Level::Warn => {
                let _ = io::stderr()
                    .write_all(msg)
                    .or_else(|_| io::stdout().write_all(msg));
            }
            _ => {
                let _ = io::stdout().write_all(msg);
            }
        }
    }

    fn flush(&self) {}
}

fn should_enable_color(stream_is_terminal: bool) -> bool {
    if !stream_is_terminal {
        return false;
    }

    if env::var_os("NO_COLOR").is_some() {
        return false;
    }
    if env::var("TERM").unwrap_or_default() == "dumb" {
        return false;
    }

    #[cfg(windows)]
    {
        enable_ansi_support::enable_ansi_support().is_ok()
    }

    #[cfg(unix)]
    {
        true
    }
}