term_colr 0.1.0

A super fast short one-liner about your crate
Documentation
use std::cell::RefCell;

#[cfg(test)]
mod test;

thread_local! {
    static COLOR_CONTEXT:RefCell<Vec<String>> = RefCell::new(vec![String::from("\x1b[37m")]);
}

#[allow(dead_code)]
pub struct ColorContext;

#[allow(dead_code)]
impl ColorContext {
    pub fn push(color: &str) {
        COLOR_CONTEXT.with(|ctx| ctx.borrow_mut().push(color.to_string()));
    }
    pub fn pop() {
        COLOR_CONTEXT.with(|ctx| {
            ctx.borrow_mut().pop();
        })
    }

    pub fn current_color() -> String {
        COLOR_CONTEXT.with(|ctx| {
            ctx.borrow()
                .last()
                .cloned()
                .unwrap_or_else(|| String::from("\x1b[37m"))
        })
    }
}
pub fn hsl_to_rgb(h: f64, s: f64, l: f64) -> (u8, u8, u8) {
    let c: f64 = (1.0 - (2.0 * l - 1.0).abs()) * s;
    let x: f64 = c * (1.0 - ((h / 60.0) % 2.0 - 1.0).abs());
    let m: f64 = l - c / 2.0;

    let (r, g, b): (f64, f64, f64) = match h {
        h if h >= 0.0 && h < 60.0 => (c, x, 0.0),
        h if h >= 60.0 && h < 120.0 => (x, c, 0.0),
        h if h >= 120.0 && h < 180.0 => (0.0, c, x),
        h if h >= 180.0 && h < 240.0 => (0.0, x, c),
        h if h >= 240.0 && h < 300.0 => (x, 0.0, c),
        h if h >= 300.0 && h <= 360.0 => (c, 0.0, x),
        _ => (0.0, 0.0, 0.0),
    };

    let r: u8 = ((r + m) * 255.0).round() as u8;
    let g: u8 = ((g + m) * 255.0).round() as u8;
    let b: u8 = ((b + m) * 255.0).round() as u8;

    (r, g, b)
}

pub fn hsv_to_rgb(h: f64, s: f64, v: f64) -> (u8, u8, u8) {
    let c: f64 = v * s;
    let x: f64 = c * (1.0 - ((h / 60.0) % 2.0 - 1.0).abs());
    let m: f64 = v - c;

    let (r, g, b): (f64, f64, f64) = match h {
        h if h >= 0.0 && h < 60.0 => (c, x, 0.0),
        h if h >= 60.0 && h < 120.0 => (x, c, 0.0),
        h if h >= 120.0 && h < 180.0 => (0.0, c, x),
        h if h >= 180.0 && h < 240.0 => (0.0, x, c),
        h if h >= 240.0 && h < 300.0 => (x, 0.0, c),
        h if h >= 300.0 && h <= 360.0 => (c, 0.0, x),
        _ => (0.0, 0.0, 0.0),
    };

    let r: u8 = ((r + m) * 255.0).round() as u8;
    let g: u8 = ((g + m) * 255.0).round() as u8;
    let b: u8 = ((b + m) * 255.0).round() as u8;

    (r, g, b)
}

pub fn reset_all() -> &'static str {
    "\x1b[0m"
}

#[macro_export]
macro_rules! apply_color {
    ($color_code:expr,$($arg:tt)*) => {{
        $crate::ColorContext::push($color_code);
        let result = format!("{}{}{}",$color_code,format!($($arg)*),$crate::reset_all());
        $crate::ColorContext::pop();
        format!("{}{}",result,$crate::ColorContext::current_color())
    }};
}

#[macro_export]
macro_rules! bg_red {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[41m",$($arg)*)
    }};
}

#[macro_export]
macro_rules! bg_blue {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[44m",$($arg)*)
    }};
}
#[macro_export]
macro_rules! bg_green {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[42m",$($arg)*)
    }};
}
#[macro_export]
macro_rules! bg_yellow {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[43m",$($arg)*)
    }};
}
#[macro_export]
macro_rules! bg_gray {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[100m",$($arg)*)
    }};
}

#[macro_export]
macro_rules! black {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[90m",$($arg)*)
    }};
}

#[macro_export]
macro_rules! red {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[31m",$($arg)*)
    }};
}

#[macro_export]
macro_rules! blue {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[34m",$($arg)*)
    }};
}

#[macro_export]
macro_rules! green {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[32m",$($arg)*)
    }};
}

#[macro_export]
macro_rules! yellow {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[33m",$($arg)*)
    }};
}

#[macro_export]
macro_rules! white {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\x1b[37m",$($arg)*)
    }};
}

#[macro_export]
macro_rules! underline {
    ($($arg:tt)*) => {
        {
            $crate::apply_color!("\033[4m",$($arg)*)
        }
    };
}

#[macro_export]
macro_rules! bold {
    ($($arg:tt)*) => {{
        $crate::apply_color!("\033[1m",$($arg)*)}
    };
}

#[macro_export]
macro_rules! italic {
    ($($arg:tt)*) => {
        {
            $crate::apply_color!("\033[3m",$($arg)*)
        }
    };
}

#[macro_export]
/// Applies a custom RGB color to the provided format string.
///
/// # Arguments
///
/// * `r` - The red component (0-255).
/// * `g` - The green component (0-255).
/// * `b` - The blue component (0-255).
/// * `args` - The format string and its arguments.
///
/// # Example
///
/// ```
// use term_colr::*;
///
// println!("{}", rgb!(255, 0, 0, "This is {} text", "bright red"));
/// ```
macro_rules! rgb {
    ($r:expr,$g:expr,$b:expr,$($arg:tt)*) => {{
        let color_code = format!("\x1b[38;2;{};{};{}m", $r, $g, $b);
        $crate::apply_color!(&color_code,$($arg)*)
    }};
}

#[macro_export]
/// Applies HSL color to the provided format string.
///
/// # Arguments
///
/// * `h` - The hue (0-360).
/// * `s` - The saturation (0-1).
/// * `l` - The lightness (0-1).
/// * `args` - The format string and its arguments.
///
/// # Example
///
/// ```
// use term_colr::*;
///
// println!("{}", hsl!(120.0, 1.0, 0.5, "This is green text"));
/// ```

macro_rules! hsl {
    ($h:expr,$s:expr,$l:expr,$($arg:tt)*) => {{
        let (r,g,b) = $crate::hsl_to_rgb($h,$s,$l);
        $crate::rgb!(r,g,b,$($arg)*)
    }};
}

#[macro_export]
/// Applies HSV color to the provided format string.
///
/// # Arguments
///
/// * `h` - The hue (0-360).
/// * `s` - The saturation (0-1).
/// * `v` - The value (0-1).
/// * `args` - The format string and its arguments.
///
/// # Example
///
/// ```
// use term_colr::*;
///
// println!("{}", hsv!(240.0, 1.0, 1.0, "This is blue text"));
/// ```

macro_rules! hsv {
    ($h:expr,$s:expr,$v:expr,$($arg:tt)*) => {{
        let (r,g,b) = $crate::hsv_to_rgb($h,$s,$v);
        $crate::rgb!(r,g,b,$($arg)*)
    }};
}

/// Applies a custom RGB background color to the provided format string.
///
/// # Arguments
///
/// * `$r` - The red component (0-255).
/// * `$g` - The green component (0-255).
/// * `$b` - The blue component (0-255).
/// * `$arg` - The format string and its arguments.
///
/// # Example
///
/// ```
// use term_colr::*;
///
// println!("{}", bg_rgb!(100, 150, 200, "This has a custom RGB background"));
/// ```

#[macro_export]
macro_rules! bg_rgb {
    ($r:expr, $g:expr, $b:expr, $($arg:tt)*) => {{
        let color_code = format!("\x1b[48;2;{};{};{}m", $r, $g, $b);
        $crate::apply_color!(&color_code, $($arg)*)
    }};
}

/// Applies a background color specified in HSL color space to the provided format string.
///
/// # Arguments
///
/// * `$h` - The hue component (0-360).
/// * `$s` - The saturation component (0-1).
/// * `$l` - The lightness component (0-1).
/// * `$arg` - The format string and its arguments.
///
/// # Example
///
/// ```
// use term_colr::*;
///
// println!("{}", bg_hsl!(180.0, 0.5, 0.5, "This has an HSL-specified background"));
/// ```
#[macro_export]
macro_rules! bg_hsl {
    ($h:expr, $s:expr, $l:expr, $($arg:tt)*) => {{
        let (r, g, b) = $crate::hsl_to_rgb($h, $s, $l);
        $crate::bg_rgb!(r, g, b, $($arg)*)
    }};
}

/// Applies a background color specified in HSV color space to the provided format string.
///
/// # Arguments
///
/// * `$h` - The hue component (0-360).
/// * `$s` - The saturation component (0-1).
/// * `$v` - The value component (0-1).
/// * `$arg` - The format string and its arguments.
///
/// # Example
///
/// ```
// use term_colr::*;
///
// println!("{}", bg_hsv!(270.0, 0.7, 0.9, "This has an HSV-specified background"));
/// ```
#[macro_export]
macro_rules! bg_hsv {
    ($h:expr, $s:expr, $v:expr, $($arg:tt)*) => {{
        let (r, g, b) = $crate::hsv_to_rgb($h, $s, $v);
        $crate::bg_rgb!(r, g, b, $($arg)*)
    }};
}