use crate::core::Rgba;
use crate::view::palette_data::{SHADES, TABLE};
const fn shade_index(shade: u16) -> usize {
let index = if shade < 100 { 0 } else { (shade as usize + 50) / 100 };
if index >= SHADES { SHADES - 1 } else { index }
}
const fn pick(hue: usize, shade: u16) -> Rgba {
Rgba::hex(TABLE[hue][shade_index(shade)])
}
macro_rules! hues {
($($index:expr => $name:ident),* $(,)?) => {
$(
#[doc = concat!("`", stringify!($name), "-<intensidad>` de Tailwind (50, 100…900, 950).")]
pub const fn $name(shade: u16) -> Rgba {
pick($index, shade)
}
)*
pub const HUES: [(&str, fn(u16) -> Rgba); 22] = [$((stringify!($name), $name as fn(u16) -> Rgba)),*];
};
}
hues! {
0 => slate, 1 => gray, 2 => zinc, 3 => neutral, 4 => stone, 5 => red, 6 => orange, 7 => amber, 8 => yellow,
9 => lime, 10 => green, 11 => emerald, 12 => teal, 13 => cyan, 14 => sky, 15 => blue, 16 => indigo,
17 => violet, 18 => purple, 19 => fuchsia, 20 => pink, 21 => rose,
}
pub const fn white() -> Rgba {
Rgba::hex(0xffffff)
}
pub const fn black() -> Rgba {
Rgba::hex(0x000000)
}
pub const fn transparent() -> Rgba {
Rgba::TRANSPARENT
}
#[cfg(test)]
mod tests {
use super::*;
fn rgb(color: Rgba) -> u32 {
let byte = |value: f32| (value * 255.0).round() as u32;
byte(color.r) << 16 | byte(color.g) << 8 | byte(color.b)
}
#[test]
fn valores_conocidos_de_tailwind() {
assert_eq!(rgb(blue(500)), 0x3b82f6);
assert_eq!(rgb(slate(900)), 0x0f172a);
assert_eq!(rgb(red(50)), 0xfef2f2);
assert_eq!(rgb(rose(950)), 0x4c0519);
assert_eq!(rgb(white()), 0xffffff);
}
#[test]
fn una_intensidad_inexistente_se_redondea() {
assert_eq!(rgb(blue(0)), rgb(blue(50)));
assert_eq!(rgb(blue(2000)), rgb(blue(950)));
assert_eq!(rgb(blue(480)), rgb(blue(500)));
}
#[test]
fn cada_tono_va_de_claro_a_oscuro() {
let luma = |c: Rgba| 0.299 * c.r + 0.587 * c.g + 0.114 * c.b;
for (name, hue) in HUES {
let shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950].map(|shade| luma(hue(shade)));
assert!(shades.windows(2).all(|pair| pair[0] > pair[1]), "{name}: {shades:?}");
}
}
#[test]
fn la_transparencia_se_conserva() {
assert_eq!(blue(500).with_alpha(0.5).a, 0.5);
}
}