Coverage Report

Created: 2025-10-13 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nu-ansi-term-0.46.0/src/gradient.rs
Line
Count
Source
1
use crate::{rgb::Rgb, Color};
2
3
/// Linear color gradient between two color stops
4
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5
pub struct Gradient {
6
    /// Start Color of Gradient
7
    pub start: Rgb,
8
9
    /// End Color of Gradient
10
    pub end: Rgb,
11
}
12
13
impl Gradient {
14
    /// Creates a new [Gradient] with two [Rgb] colors, `start` and `end`
15
    #[inline]
16
0
    pub const fn new(start: Rgb, end: Rgb) -> Self {
17
0
        Self { start, end }
18
0
    }
19
0
    pub const fn from_color_rgb(start: Color, end: Color) -> Self {
20
0
        let start_grad = match start {
21
0
            Color::Rgb(r, g, b) => Rgb { r, g, b },
22
0
            _ => Rgb { r: 0, g: 0, b: 0 },
23
        };
24
0
        let end_grad = match end {
25
0
            Color::Rgb(r, g, b) => Rgb { r, g, b },
26
0
            _ => Rgb { r: 0, g: 0, b: 0 },
27
        };
28
29
0
        Self {
30
0
            start: start_grad,
31
0
            end: end_grad,
32
0
        }
33
0
    }
34
35
    /// Computes the [Rgb] color between `start` and `end` for `t`
36
0
    pub fn at(&self, t: f32) -> Rgb {
37
0
        self.start.lerp(self.end, t)
38
0
    }
39
40
    /// Returns the reverse of `self`
41
    #[inline]
42
0
    pub const fn reverse(&self) -> Self {
43
0
        Self::new(self.end, self.start)
44
0
    }
45
46
    #[allow(dead_code)]
47
0
    pub fn build(&self, text: &str, target: TargetGround) -> String {
48
0
        let delta = 1.0 / text.len() as f32;
49
0
        let mut result = text.char_indices().fold(String::new(), |mut acc, (i, c)| {
50
0
            let temp = format!(
51
0
                "\x1B[{}m{}",
52
0
                self.at(i as f32 * delta).ansi_color_code(target),
53
                c
54
            );
55
0
            acc.push_str(&temp);
56
0
            acc
57
0
        });
58
59
0
        result.push_str("\x1B[0m");
60
0
        result
61
0
    }
62
}
63
64
#[allow(dead_code)]
65
0
pub fn build_all_gradient_text(text: &str, foreground: Gradient, background: Gradient) -> String {
66
0
    let delta = 1.0 / text.len() as f32;
67
0
    let mut result = text.char_indices().fold(String::new(), |mut acc, (i, c)| {
68
0
        let step = i as f32 * delta;
69
0
        let temp = format!(
70
0
            "\x1B[{};{}m{}",
71
0
            foreground
72
0
                .at(step)
73
0
                .ansi_color_code(TargetGround::Foreground),
74
0
            background
75
0
                .at(step)
76
0
                .ansi_color_code(TargetGround::Background),
77
            c
78
        );
79
0
        acc.push_str(&temp);
80
0
        acc
81
0
    });
82
83
0
    result.push_str("\x1B[0m");
84
0
    result
85
0
}
86
87
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
88
pub enum TargetGround {
89
    Foreground,
90
    Background,
91
}
92
93
impl TargetGround {
94
    #[inline]
95
0
    pub const fn code(&self) -> u8 {
96
0
        match self {
97
0
            Self::Foreground => 30,
98
0
            Self::Background => 40,
99
        }
100
0
    }
101
}
102
103
pub trait ANSIColorCode {
104
    fn ansi_color_code(&self, target: TargetGround) -> String;
105
}