about summary refs log tree commit diff stats
path: root/crates/colors/src/custom.rs
blob: fd6b7b382b0a93ee22b70e7aa14fdc8cd204ca3c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// yt - A fully featured command line YouTube client
//
// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This file is part of Yt.
//
// You should have received a copy of the License along with this program.
// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.

// Taken from <https://github.com/owo-colors/owo-colors/blob/61f8bba2f5f80e9f4fa600fbfdf2c21656f1d523/src/colors/custom.rs>
// at 2025-07-16T18:05:55 CEST.

const U8_TO_STR: [[u8; 3]; 256] = generate_lookup();

const fn generate_lookup() -> [[u8; 3]; 256] {
    let mut table = [[0, 0, 0]; 256];

    let mut i = 0;
    while i < 256 {
        table[i] = [
            b'0' + (i / 100) as u8,
            b'0' + (i / 10 % 10) as u8,
            b'0' + (i % 10) as u8,
        ];
        i += 1;
    }

    table
}

#[derive(Clone, Copy)]
pub(crate) enum Plane {
    Fg,
    Bg,
}

pub(crate) const fn rgb_to_ansi(r: u8, g: u8, b: u8, plane: Plane) -> [u8; 18] {
    let mut buf = *b"\x1b[p8;2;rrr;ggg;bbb";

    let r = U8_TO_STR[r as usize];
    let g = U8_TO_STR[g as usize];
    let b = U8_TO_STR[b as usize];

    // p 2
    buf[2] = match plane {
        Plane::Fg => b'3',
        Plane::Bg => b'4',
    };

    // r 7
    buf[7] = r[0];
    buf[8] = r[1];
    buf[9] = r[2];

    // g 11
    buf[11] = g[0];
    buf[12] = g[1];
    buf[13] = g[2];

    // b 15
    buf[15] = b[0];
    buf[16] = b[1];
    buf[17] = b[2];

    buf
}

/// This exists since [`unwrap()`] isn't const-safe (it invokes formatting infrastructure)
pub(crate) const fn bytes_to_str(bytes: &'static [u8]) -> &'static str {
    match core::str::from_utf8(bytes) {
        Ok(o) => o,
        Err(_e) => panic!("Const parsing &[u8] to a string failed!"),
    }
}