aurora-modules 0.1.0

Git, filesystem, system, network, archive, docker, unix, crypto, calculator, QR, color, timer, notes, clipboard, and text processing modules
Documentation
use aurora_core::{AuroraResult, Pipeline, Value};

fn ansi_hex(code: u8) -> String {
    let r = ((code >> 5) & 7) as f64 / 7.0 * 255.0;
    let g = ((code >> 2) & 7) as f64 / 7.0 * 255.0;
    let b = (code & 3) as f64 / 3.0 * 255.0;
    format!("#{:02x}{:02x}{:02x}", r as u8, g as u8, b as u8)
}

pub fn color_palette() -> AuroraResult<Pipeline> {
    let mut rows: Vec<Vec<Value>> = Vec::new();

    for i in 0..=255 {
        let hex = ansi_hex(i);
        let sample = format!("\x1b[48;5;{}m  \x1b[0m", i);
        rows.push(vec![
            Value::Int(i as i64),
            Value::String(sample),
            Value::String(hex),
        ]);
    }

    Ok(Pipeline::table(
        vec!["code".into(), "sample".into(), "hex".into()],
        rows,
    ))
}

fn hex_to_rgb(hex: &str) -> Option<(u8, u8, u8)> {
    let hex = hex.trim_start_matches('#');
    if hex.len() != 6 { return None; }
    let r = u8::from_str_radix(&hex[0..2], 16).ok()?;
    let g = u8::from_str_radix(&hex[2..4], 16).ok()?;
    let b = u8::from_str_radix(&hex[4..6], 16).ok()?;
    Some((r, g, b))
}

fn rgb_to_ansi(r: u8, g: u8, b: u8) -> u8 {
    let r_idx = (r as f64 / 255.0 * 5.0).round() as u8;
    let g_idx = (g as f64 / 255.0 * 5.0).round() as u8;
    let b_idx = (b as f64 / 255.0 * 5.0).round() as u8;
    16 + r_idx * 36 + g_idx * 6 + b_idx
}

pub fn color_hex(hex: &str) -> AuroraResult<Pipeline> {
    let (r, g, b) = hex_to_rgb(hex).ok_or_else(|| {
        aurora_core::AuroraError::InvalidInput(
            format!("invalid hex color: {}", hex)
        )
    })?;

    let ansi = rgb_to_ansi(r, g, b);

    let mut record = std::collections::BTreeMap::new();
    record.insert("hex".into(), Value::String(hex.into()));
    record.insert("r".into(), Value::Int(r as i64));
    record.insert("g".into(), Value::Int(g as i64));
    record.insert("b".into(), Value::Int(b as i64));
    record.insert("ansi_code".into(), Value::Int(ansi as i64));

    Ok(Pipeline::single(Value::Record(record)))
}

pub fn color_rgb(r: u8, g: u8, b: u8) -> AuroraResult<Pipeline> {
    let hex = format!("#{:02x}{:02x}{:02x}", r, g, b);
    let ansi = rgb_to_ansi(r, g, b);

    let mut record = std::collections::BTreeMap::new();
    record.insert("hex".into(), Value::String(hex));
    record.insert("r".into(), Value::Int(r as i64));
    record.insert("g".into(), Value::Int(g as i64));
    record.insert("b".into(), Value::Int(b as i64));
    record.insert("ansi_code".into(), Value::Int(ansi as i64));

    Ok(Pipeline::single(Value::Record(record)))
}