use thag_styling::{
auto_help, display_color_comparison, help_system::check_help_and_exit, hsl_to_rgb, ColorValue,
Style, TermAttributes,
};
fn main() {
let help = auto_help!();
check_help_and_exit(&help);
println!("🎨 Terminal Palette Display Tool");
println!("================================\n");
display_terminal_info();
display_ansi_colors();
display_256_color_samples();
display_true_color_test();
display_thag_theme_colors();
println!(
"💡 Comparing with your configured or detected `thag_styling` theme's palette colors:"
);
let term_attrs = TermAttributes::get_or_init();
let theme = &term_attrs.theme;
display_color_comparison(theme);
println!("\n🎉 Palette display complete!");
}
fn display_terminal_info() {
println!("📟 Terminal Information:");
println!("========================");
let term_attrs = TermAttributes::get_or_init();
println!("🔍 Color Support: {:?}", term_attrs.color_support);
println!("🌓 Background Luma: {:?}", term_attrs.term_bg_luma);
if let Ok(term) = std::env::var("TERM") {
println!("🖥️ TERM: {}", term);
}
if let Ok(colorterm) = std::env::var("COLORTERM") {
println!("🌈 COLORTERM: {}", colorterm);
}
println!();
}
fn display_ansi_colors() {
println!("🎨 ANSI Color Palette (0-15):");
println!("==============================");
println!("Standard Colors (0-7):");
display_color_row(&[
(0, "Black"),
(1, "Red"),
(2, "Green"),
(3, "Yellow"),
(4, "Blue"),
(5, "Magenta"),
(6, "Cyan"),
(7, "White"),
]);
println!();
println!("Bright Colors (8-15):");
display_color_row(&[
(8, "Bright Black"),
(9, "Bright Red"),
(10, "Bright Green"),
(11, "Bright Yellow"),
(12, "Bright Blue"),
(13, "Bright Magenta"),
(14, "Bright Cyan"),
(15, "Bright White"),
]);
println!();
}
fn display_color_row(colors: &[(u8, &str)]) {
print!(" ");
for (index, _) in colors {
print!("{:>12}", index);
}
println!();
print!(" ");
for (_, name) in colors {
print!("{:>12}", name);
}
println!();
print!(" ");
for (index, _) in colors {
print!("\x1b[48;5;{}m{:>12}\x1b[0m", index, "");
}
println!();
print!(" ");
for (index, _) in colors {
print!("\x1b[38;5;{}m{:>12}\x1b[0m", index, "Sample");
}
println!();
}
fn display_256_color_samples() {
println!("🌈 256-Color Palette Samples:");
println!("==============================");
println!("Color Cube (16-231) - Representative Sample:");
for row in 0..6 {
print!(" ");
for col in 0..6 {
let index = 16 + row * 36 + col * 6;
print!("\x1b[48;5;{}m {:3} \x1b[0m", index, index);
}
println!();
}
println!();
println!("Grayscale Ramp (232-255):");
print!(" ");
for i in 232..=255 {
if (i - 232) % 12 == 0 && i > 232 {
println!();
print!(" ");
}
print!("\x1b[48;5;{}m {:3} \x1b[0m", i, i);
}
println!();
println!();
}
#[allow(clippy::cast_precision_loss)]
fn display_true_color_test() {
println!("🌟 True Color (24-bit) Test:");
println!("=============================");
println!("Red → Blue Gradient:");
print!(" ");
for i in 0..32 {
let red = 255 - (i * 8);
let blue = i * 8;
print!("\x1b[48;2;{};0;{}m \x1b[0m", red, blue);
}
println!();
println!("Green Gradient:");
print!(" ");
for i in 0..32 {
let green = i * 8;
print!("\x1b[48;2;0;{};0m \x1b[0m", green);
}
println!();
println!("Rainbow Spectrum:");
print!(" ");
for i in 0..32 {
let hue = (i as f32 / 32.0) * 360.0;
let [r, g, b] = hsl_to_rgb(hue, 1.0, 0.5);
print!("\x1b[48;2;{};{};{}m \x1b[0m", r, g, b);
}
println!();
println!();
}
fn display_thag_theme_colors() {
println!("🎯 Current Thag Theme Colors:");
println!("==============================");
let term_attrs = TermAttributes::get_or_init();
let theme = &term_attrs.theme;
println!("Theme: {}", theme.name);
println!("Description: {}", theme.description);
println!("Background: {:?}", theme.bg_rgbs);
println!();
let semantic_colors = [
("Normal", &theme.palette.normal),
("Error", &theme.palette.error),
("Warning", &theme.palette.warning),
("Success", &theme.palette.success),
("Info", &theme.palette.info),
("Code", &theme.palette.code),
("Emphasis", &theme.palette.emphasis),
("Subtle", &theme.palette.subtle),
("Heading1", &theme.palette.heading1),
("Heading2", &theme.palette.heading2),
("Heading3", &theme.palette.heading3),
];
println!("Semantic Colors:");
for (name, style) in semantic_colors {
let colored_text = style.paint(format!("{:>12}", name));
let rgb_info = extract_rgb_info(style);
println!(" {colored_text} - {rgb_info}");
}
println!();
if let Some([r, g, b]) = theme.bg_rgbs.first() {
println!("Background Color Preview:");
print!(" ");
for _ in 0..20 {
print!("\x1b[48;2;{};{};{}m \x1b[0m", r, g, b);
}
println!(" RGB({}, {}, {})", r, g, b);
}
}
fn extract_rgb_info(style: &Style) -> String {
style.foreground.as_ref().map_or_else(
|| "No color".to_string(),
|color_info| match &color_info.value {
ColorValue::TrueColor { rgb } => {
format!("RGB({}, {}, {})", rgb[0], rgb[1], rgb[2])
}
ColorValue::Color256 { color256 } => {
format!("256-Color({})", color256)
}
ColorValue::Basic { index, .. } => {
format!("Basic({})", index)
}
},
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_extract_rgb_info() {
let style = Style::fg(thag_styling::ColorInfo::rgb(255, 128, 64));
let info = extract_rgb_info(&style);
assert_eq!(info, "RGB(255, 128, 64)");
}
}