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() {
assert_eq!(darken("#ffffff", 20), "#ebebeb");
assert_eq!(darken("#f1f1f1", 20), "#dddddd");
assert_eq!(darken("#fff", 20), "#ebebeb");
assert_eq!(darken("#fe3", 20), "#ebda1f");
assert_eq!(darken("#ffee33", 20), "#ebda1f");
assert_eq!(darken("#000000", 20), "#000000");
assert_eq!(darken("#101010", 20), "#000000");
assert_eq!(darken("#123456", 0), "#123456");
}
}