davis 0.1.1

An CLI client for MPD.
use std::env;
use std::fmt;
use std::sync::atomic::{AtomicBool, Ordering};

#[allow(dead_code)]
#[derive(Clone, Copy)]
pub enum Style {
    Bold = 1,
    Faint = 2,
    Underline = 4,
    Default = 0,
}

pub struct FormattedString<'a> {
    pub style: Option<Style>,
    pub string: &'a str,
}

impl<'a> FormattedString<'a> {
    pub fn style(self, style: Style) -> FormattedString<'a> {
        FormattedString {
            style: Some(style),
            ..self
        }
    }

    pub fn new(string: &'a str) -> FormattedString<'a> {
        FormattedString {
            style: None,
            string,
        }
    }
}

impl<'a> fmt::Display for FormattedString<'a> {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        if is_dumb_terminal() {
            formatter.pad(&*self.string)?;
            return Ok(());
        }

        if let Some(style) = self.style {
            write!(formatter, "\x1B[{}m", style as u8)?;
            formatter.pad(&*self.string)?;
            write!(formatter, "\x1B[{}m", Style::Default as u8)?;
        } else {
            formatter.pad(&*self.string)?;
        }
        Ok(())
    }
}

pub static PLAIN_FORMATTING: AtomicBool = AtomicBool::new(false);
pub fn is_dumb_terminal() -> bool {
    let is_dumb = matches!(env::var("TERM"), Ok(s) if s == "dumb");
    let has_no_color = env::var("NO_COLOR").is_ok();

    is_dumb || has_no_color || PLAIN_FORMATTING.load(Ordering::Relaxed)
}