codesnap/utils/
color.rs

1use std::i64;
2use tiny_skia::Color;
3
4const HEX_COLOR_LENGTH: usize = 7;
5const HEX_COLOR_WITH_ALPHA_LENGTH: usize = 9;
6
7pub struct RgbaColor(Color);
8
9pub fn is_valid_hex_color(color: &str) -> bool {
10    (color.len() == HEX_COLOR_LENGTH || color.len() == HEX_COLOR_WITH_ALPHA_LENGTH)
11        && color.starts_with("#")
12}
13
14fn parse_color_to_rgba_hex(hex: &str) -> String {
15    if !is_valid_hex_color(&hex) || hex.len() == HEX_COLOR_WITH_ALPHA_LENGTH {
16        hex.to_string()
17    } else {
18        format!("{}ff", hex)
19    }
20}
21
22pub fn parse_hex_to_cosmic_color(hex: &str) -> cosmic_text::Color {
23    let color: RgbaColor = hex.into();
24
25    color.into()
26}
27
28impl Into<RgbaColor> for &str {
29    fn into(self) -> RgbaColor {
30        if !is_valid_hex_color(&self) {
31            panic!("Invalid hex color: {}", self);
32        }
33
34        let rgba_hex_color = parse_color_to_rgba_hex(&self);
35        // Remove the '#' symbol
36        let hex_color = &rgba_hex_color.to_lowercase()[1..rgba_hex_color.len()];
37        let chars = hex_color.chars().collect::<Vec<char>>();
38        let splits = &chars
39            .chunks(2)
40            .map(|chunk| i64::from_str_radix(&chunk.iter().collect::<String>(), 16).unwrap())
41            .collect::<Vec<_>>();
42
43        RgbaColor(Color::from_rgba8(
44            splits[0] as u8,
45            splits[1] as u8,
46            splits[2] as u8,
47            splits[3] as u8,
48        ))
49    }
50}
51
52impl From<RgbaColor> for cosmic_text::Color {
53    fn from(value: RgbaColor) -> Self {
54        let color = value.0.to_color_u8();
55
56        cosmic_text::Color::rgba(color.red(), color.green(), color.blue(), color.alpha())
57    }
58}
59
60impl From<RgbaColor> for Color {
61    fn from(value: RgbaColor) -> Self {
62        value.0
63    }
64}