Color/
lib.rs

1#![allow(non_snake_case)]
2
3/// Get luminance from rgb.
4/// ### Examples
5/// ```
6/// let lum = Color::luminance([255, 255, 255]);
7/// assert_eq!(1.0, lum);
8/// ```
9pub fn luminance(rgb: [u8; 3]) -> f64 {
10    let mut arr = [0.; 3];
11    for i in 0..=2 {
12        let color = (rgb[i] as f64) / 255.;
13        arr[i] = if color <= 0.03928 {
14            color / 12.92
15        } else {
16            ((color + 0.055) / 1.055).powf(2.4)
17        };
18    }
19    arr[0] * 0.2126 + arr[1] * 0.7152 + arr[2] * 0.0722
20}
21
22/// Create RGB instance.
23pub struct RGB(pub [u8; 3]);
24
25impl RGB {
26    /// Get RGB value.
27    pub fn value(&self) -> [u8; 3] {
28        self.0
29    }
30    /// Inverted rgb value.
31    pub fn inverted(&mut self) -> &mut Self {
32        let rgb = &mut self.0;
33        for color in rgb.iter_mut() {
34            *color = 255 - *color;
35        }
36        self
37    }
38    /// convart rgb value to hex value.
39    pub fn to_hex(&self) -> String {
40        let rgb = self.0;
41        format!("{:02x}{:02x}{:02x}", rgb[0], rgb[1], rgb[2])
42    }
43    /// Get contrast ratio between two colors.
44    pub fn contrast_ratio(&self, rgb: [u8; 3]) -> f64 {
45        let lum1 = luminance(rgb);
46        let lum2 = luminance(self.0);
47        (lum1.max(lum2) + 0.05) / (lum1.min(lum2) + 0.05)
48    }
49    /// Create RGB instance from hex value.
50    /// ### Examples
51    /// ```
52    /// RGB::from_hex("#00ff00").unwrap();
53    /// ```
54    pub fn from_hex(hex_value: &str) -> Result<Self, &str> {
55        let hex = hex_value.trim_start_matches("#");
56        let mut rgb = [0u8; 3];
57        if hex.len() != 6 {
58            return Err("Invalid Color");
59        }
60        for i in 0..=2 {
61            let x = i * 2;
62            match u8::from_str_radix(&hex[x..(x + 2)], 16) {
63                Ok(color) => rgb[i] = color,
64                Err(_) => return Err("Invalid Digit"),
65            }
66        }
67        Ok(Self(rgb))
68    }
69}