coloriz 0.2.0

A simple library for colorful temrinal
Documentation
use crate::{ANSIColorCode, TargetGround, RGB};

/// Linear color gradient between two color stops
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Gradient {
    pub start: RGB,
    pub end: RGB,
}

impl Gradient {
    /// Creates a new [Gradient] with two [RGB] colors, `start` and `end`
    #[inline]
    pub const fn new(start: RGB, end: RGB) -> Self {
        Self { start, end }
    }

    /// Computes the [RGB] color between `start` and `end` for `t`
    pub fn at(&self, t: f32) -> RGB {
        self.start.lerp(self.end, t)
    }

    /// Returns the reverse of `self`
    #[inline]
    pub const fn reverse(&self) -> Self {
        Self::new(self.end, self.start)
    }

    pub(crate) fn build(&self, text: &str, target: TargetGround) -> String {
        let delta = 1.0 / text.len() as f32;
        let mut result = text.char_indices().fold(String::new(), |mut acc, (i, c)| {
            let temp = format!(
                "\x1B[{}m{}",
                self.at(i as f32 * delta).ansi_color_code(target),
                c
            );
            acc.push_str(&temp);
            acc
        });

        result.push_str("\x1B[0m");
        result
    }
}

pub(crate) fn build_all_gradient_text(
    text: &str,
    foreground: Gradient,
    background: Gradient,
) -> String {
    let delta = 1.0 / text.len() as f32;
    let mut result = text.char_indices().fold(String::new(), |mut acc, (i, c)| {
        let step = i as f32 * delta;
        let temp = format!(
            "\x1B[{};{}m{}",
            foreground
                .at(step)
                .ansi_color_code(TargetGround::Foreground),
            background
                .at(step)
                .ansi_color_code(TargetGround::Background),
            c
        );
        acc.push_str(&temp);
        acc
    });

    result.push_str("\x1B[0m");
    result
}