animatar 1.0.1

A blazingly fast, deterministic animal avatar generator.
Documentation
pub fn darken(hex: &str, amount: i16) -> String {
    let mut rgb = hex_to_rgb(hex);
    for c in &mut rgb {
        *c = (*c as i16 - amount).clamp(0, 255) as u8;
    }
    rgb_to_hex(&rgb)
}

fn hex_to_rgb(hex: &str) -> [u8; 3] {
    let hex = hex.trim_start_matches('#');
    let hex = if hex.len() == 3 {
        hex.chars()
            .map(|c| c.to_string() + &c.to_string())
            .collect::<String>()
    } else {
        hex.to_string()
    };

    let r = u8::from_str_radix(&hex[0..2], 16).unwrap();
    let g = u8::from_str_radix(&hex[2..4], 16).unwrap();
    let b = u8::from_str_radix(&hex[4..6], 16).unwrap();

    [r, g, b]
}

fn rgb_to_hex(rgb: &[u8; 3]) -> String {
    format!("#{:02x}{:02x}{:02x}", rgb[0], rgb[1], rgb[2])
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_darken_colors() {
        // Test with a standard 6-digit hex
        assert_eq!(darken("#ffffff", 20), "#ebebeb");
        assert_eq!(darken("#f1f1f1", 20), "#dddddd");

        // Test with a 3-digit hex (should be treated the same as 6-digit)
        assert_eq!(darken("#fff", 20), "#ebebeb");
        assert_eq!(darken("#fe3", 20), "#ebda1f");
        assert_eq!(darken("#ffee33", 20), "#ebda1f");

        // Test clamping at black
        assert_eq!(darken("#000000", 20), "#000000");
        assert_eq!(darken("#101010", 20), "#000000");

        // Test darkening by 0
        assert_eq!(darken("#123456", 0), "#123456");
    }
}