material_color_utilities/utils/
string.rs

1use std::convert::Infallible;
2
3use crate::utils::color::{
4  alpha_from_argb, argb_from_rgb, blue_from_argb, green_from_argb, red_from_argb,
5};
6
7use csscolorparser::{Color, ParseColorError};
8pub use csscolorparser::{Color as CssColor, ParseColorError as Error};
9
10#[inline]
11pub fn hex_from_argb(argb: u32) -> String {
12  let r = red_from_argb(argb);
13  let g = green_from_argb(argb);
14  let b = blue_from_argb(argb);
15  format!("#{r:02x}{g:02x}{b:02x}")
16}
17
18pub fn argb_from_hex(hex: &str) -> Result<u32, ParseColorError> {
19  let hex = hex.trim();
20  if !hex.starts_with("#") {
21    return Err(ParseColorError::InvalidHex);
22  }
23  let color = hex.parse::<Color>()?;
24  let [r, g, b, _] = color.to_rgba8();
25  let argb = argb_from_rgb(r, g, b);
26  Ok(argb)
27}
28
29pub fn css_hex_from_argb(argb: u32) -> String {
30  Color::from_argb(argb).to_css_hex()
31}
32
33pub fn argb_from_css_hex(hex: &str) -> Result<u32, ParseColorError> {
34  let hex = hex.trim();
35  if hex.starts_with("#") {
36    argb_from_css_color(hex)
37  } else {
38    Err(ParseColorError::InvalidHex)
39  }
40}
41
42pub fn argb_from_css_color(css_color: &str) -> Result<u32, ParseColorError> {
43  css_color.try_parse_argb()
44}
45
46pub trait ParseArgb: Sized {
47  fn parse_argb(self) -> u32;
48}
49
50pub trait TryParseArgb: Sized {
51  type Error;
52
53  fn try_parse_argb(self) -> Result<u32, Self::Error>;
54}
55
56impl<T> TryParseArgb for T
57where
58  T: ParseArgb,
59{
60  type Error = Infallible;
61
62  fn try_parse_argb(self) -> Result<u32, Self::Error> {
63    Ok(self.parse_argb())
64  }
65}
66
67impl TryParseArgb for &str {
68  type Error = ParseColorError;
69
70  fn try_parse_argb(self) -> Result<u32, Self::Error> {
71    self.parse::<Color>().map(ParseArgb::parse_argb)
72  }
73}
74
75impl ParseArgb for Color {
76  fn parse_argb(self) -> u32 {
77    let [r, g, b, a] = self.to_rgba8();
78    ((a as u32) << 24) | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
79  }
80}
81
82pub trait FromArgb: Sized {
83  fn from_argb(argb: u32) -> Self;
84}
85
86pub trait TryFromArgb: Sized {
87  type Error;
88
89  fn try_from_argb(argb: u32) -> Result<Self, Self::Error>;
90}
91
92impl<T> TryFromArgb for T
93where
94  T: FromArgb,
95{
96  type Error = Infallible;
97
98  fn try_from_argb(argb: u32) -> Result<Self, Self::Error> {
99    Ok(Self::from_argb(argb))
100  }
101}
102
103impl FromArgb for Color {
104  fn from_argb(argb: u32) -> Self {
105    let r = red_from_argb(argb);
106    let g = green_from_argb(argb);
107    let b = blue_from_argb(argb);
108    let a = alpha_from_argb(argb);
109    Self::from_rgba8(r, g, b, a)
110  }
111}