Skip to main content

aurora_modules/
color.rs

1use aurora_core::{AuroraResult, Pipeline, Value};
2
3fn ansi_hex(code: u8) -> String {
4    let r = ((code >> 5) & 7) as f64 / 7.0 * 255.0;
5    let g = ((code >> 2) & 7) as f64 / 7.0 * 255.0;
6    let b = (code & 3) as f64 / 3.0 * 255.0;
7    format!("#{:02x}{:02x}{:02x}", r as u8, g as u8, b as u8)
8}
9
10pub fn color_palette() -> AuroraResult<Pipeline> {
11    let mut rows: Vec<Vec<Value>> = Vec::new();
12
13    for i in 0..=255 {
14        let hex = ansi_hex(i);
15        let sample = format!("\x1b[48;5;{}m  \x1b[0m", i);
16        rows.push(vec![
17            Value::Int(i as i64),
18            Value::String(sample),
19            Value::String(hex),
20        ]);
21    }
22
23    Ok(Pipeline::table(
24        vec!["code".into(), "sample".into(), "hex".into()],
25        rows,
26    ))
27}
28
29fn hex_to_rgb(hex: &str) -> Option<(u8, u8, u8)> {
30    let hex = hex.trim_start_matches('#');
31    if hex.len() != 6 { return None; }
32    let r = u8::from_str_radix(&hex[0..2], 16).ok()?;
33    let g = u8::from_str_radix(&hex[2..4], 16).ok()?;
34    let b = u8::from_str_radix(&hex[4..6], 16).ok()?;
35    Some((r, g, b))
36}
37
38fn rgb_to_ansi(r: u8, g: u8, b: u8) -> u8 {
39    let r_idx = (r as f64 / 255.0 * 5.0).round() as u8;
40    let g_idx = (g as f64 / 255.0 * 5.0).round() as u8;
41    let b_idx = (b as f64 / 255.0 * 5.0).round() as u8;
42    16 + r_idx * 36 + g_idx * 6 + b_idx
43}
44
45pub fn color_hex(hex: &str) -> AuroraResult<Pipeline> {
46    let (r, g, b) = hex_to_rgb(hex).ok_or_else(|| {
47        aurora_core::AuroraError::InvalidInput(
48            format!("invalid hex color: {}", hex)
49        )
50    })?;
51
52    let ansi = rgb_to_ansi(r, g, b);
53
54    let mut record = std::collections::BTreeMap::new();
55    record.insert("hex".into(), Value::String(hex.into()));
56    record.insert("r".into(), Value::Int(r as i64));
57    record.insert("g".into(), Value::Int(g as i64));
58    record.insert("b".into(), Value::Int(b as i64));
59    record.insert("ansi_code".into(), Value::Int(ansi as i64));
60
61    Ok(Pipeline::single(Value::Record(record)))
62}
63
64pub fn color_rgb(r: u8, g: u8, b: u8) -> AuroraResult<Pipeline> {
65    let hex = format!("#{:02x}{:02x}{:02x}", r, g, b);
66    let ansi = rgb_to_ansi(r, g, b);
67
68    let mut record = std::collections::BTreeMap::new();
69    record.insert("hex".into(), Value::String(hex));
70    record.insert("r".into(), Value::Int(r as i64));
71    record.insert("g".into(), Value::Int(g as i64));
72    record.insert("b".into(), Value::Int(b as i64));
73    record.insert("ansi_code".into(), Value::Int(ansi as i64));
74
75    Ok(Pipeline::single(Value::Record(record)))
76}