upgate-presentation 0.1.1

Keep globally installed developer tools up to date
Documentation
use std::io::IsTerminal;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum OutputMode {
    Plain,
    Styled { color: bool },
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct OutputTheme {
    mode: OutputMode,
    pub verbose: bool,
}

impl OutputTheme {
    pub fn from_environment(options: ThemeOptions) -> Self {
        Self::from_terminal(
            options,
            TerminalCapabilities {
                stdout_is_tty: std::io::stdout().is_terminal(),
                no_color_env: std::env::var_os("NO_COLOR").is_some_and(|value| !value.is_empty()),
                term_is_dumb: std::env::var_os("TERM").is_some_and(|value| value == "dumb"),
            },
        )
    }
    pub const fn from_terminal(options: ThemeOptions, capabilities: TerminalCapabilities) -> Self {
        let plain = options.plain || !capabilities.stdout_is_tty;
        let mode = if plain {
            OutputMode::Plain
        } else {
            OutputMode::Styled {
                color: !options.no_color
                    && !capabilities.no_color_env
                    && !capabilities.term_is_dumb,
            }
        };

        Self {
            mode,
            verbose: options.verbose,
        }
    }
    pub const fn is_plain(self) -> bool {
        matches!(self.mode, OutputMode::Plain)
    }
    pub const fn color(self) -> bool {
        match self.mode {
            OutputMode::Plain => false,
            OutputMode::Styled { color } => color,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct ThemeOptions {
    pub plain: bool,
    pub no_color: bool,
    pub verbose: bool,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TerminalCapabilities {
    pub stdout_is_tty: bool,
    pub no_color_env: bool,
    pub term_is_dumb: bool,
}