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}