#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Color {
pub r: f64,
pub g: f64,
pub b: f64,
pub a: f64,
}
impl Color {
pub fn rgb(r: f64, g: f64, b: f64) -> Self {
Color { r, g, b, a: 1.0 }
}
pub fn rgba(r: f64, g: f64, b: f64, a: f64) -> Self {
Color { r, g, b, a }
}
pub fn gray(value: f64) -> Self {
Color {
r: value,
g: value,
b: value,
a: 1.0,
}
}
pub fn parse(s: &str) -> Self {
s.parse::<csscolorparser::Color>()
.map(|c| {
let [r, g, b, a] = c.to_array();
Color {
r: r.into(),
g: g.into(),
b: b.into(),
a: a.into(),
}
})
.unwrap_or(Color::BLACK)
}
pub fn hex(hex: &str) -> Self {
let hex = hex.trim_start_matches('#');
if let Ok(c) = format!("#{}", hex).parse::<csscolorparser::Color>() {
let [r, g, b, a] = c.to_array();
return Color {
r: r.into(),
g: g.into(),
b: b.into(),
a: a.into(),
};
}
Color::BLACK
}
pub const BLACK: Color = Color {
r: 0.0,
g: 0.0,
b: 0.0,
a: 1.0,
};
pub const WHITE: Color = Color {
r: 1.0,
g: 1.0,
b: 1.0,
a: 1.0,
};
pub const RED: Color = Color {
r: 1.0,
g: 0.0,
b: 0.0,
a: 1.0,
};
pub const GREEN: Color = Color {
r: 0.0,
g: 1.0,
b: 0.0,
a: 1.0,
};
pub const BLUE: Color = Color {
r: 0.0,
g: 0.0,
b: 1.0,
a: 1.0,
};
}
impl Default for Color {
fn default() -> Self {
Color::BLACK
}
}
impl core::str::FromStr for Color {
type Err = csscolorparser::ParseColorError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let c = s.parse::<csscolorparser::Color>()?;
let [r, g, b, a] = c.to_array();
Ok(Color {
r: r.into(),
g: g.into(),
b: b.into(),
a: a.into(),
})
}
}
impl From<csscolorparser::Color> for Color {
fn from(c: csscolorparser::Color) -> Self {
let [r, g, b, a] = c.to_array();
Color {
r: r.into(),
g: g.into(),
b: b.into(),
a: a.into(),
}
}
}
#[derive(Debug, Clone)]
pub enum ColorInput {
Css(String),
Color(Color),
}
impl ColorInput {
pub fn to_color(&self) -> Color {
match self {
ColorInput::Css(s) => Color::parse(s),
ColorInput::Color(c) => *c,
}
}
}
impl From<&str> for ColorInput {
fn from(s: &str) -> Self {
ColorInput::Css(s.to_string())
}
}
impl From<String> for ColorInput {
fn from(s: String) -> Self {
ColorInput::Css(s)
}
}
impl From<Color> for ColorInput {
fn from(c: Color) -> Self {
ColorInput::Color(c)
}
}
impl From<&Color> for ColorInput {
fn from(c: &Color) -> Self {
ColorInput::Color(*c)
}
}
impl From<(f64, f64, f64)> for ColorInput {
fn from((r, g, b): (f64, f64, f64)) -> Self {
ColorInput::Color(Color::rgb(r, g, b))
}
}
impl From<[f64; 3]> for ColorInput {
fn from([r, g, b]: [f64; 3]) -> Self {
ColorInput::Color(Color::rgb(r, g, b))
}
}