use super::{Style, StyleUpdater};
use palette::{FromColor, IntoColor, Packed, Srgb, Srgba};
pub use palette::{self, named};
pub fn display_rgb(rgb: &Srgb) -> String {
let (red, green, blue) = rgb.into_components();
format!(
"rgb({:.2}%, {:.2}%, {:.2}%)",
(red * 100.0),
green * 100.0,
blue * 100.0
)
}
pub fn display_rgba(rgb: &Srgba) -> String {
let (red, green, blue, alpha) = rgb.into_components();
format!(
"rgba({:.2}%, {:.2}%, {:.2}%, {})",
red * 100.0,
green * 100.0,
blue * 100.0,
alpha
)
}
pub fn display_rgb_u8(rgb: &Srgb<u8>) -> String {
let (red, green, blue) = rgb.into_components();
format!("rgb({}, {}, {})", red, green, blue)
}
pub fn display_rgba_u8(rgb: &Srgba<u8>) -> String {
let (red, green, blue, alpha) = rgb.into_components();
format!("rgba({}, {}, {}, {})", red, green, blue, alpha)
}
#[derive(Clone, Copy, Debug, PartialEq, Display, From)]
pub enum Color {
#[from]
#[display(fmt = "{}", "display_rgb(_0)")]
Rgb(Srgb),
#[from]
#[display(fmt = "{}", "display_rgba(_0)")]
Rgba(Srgba),
#[from]
#[display(fmt = "{}", "display_rgba_u8(_0)")]
RgbaU8(Srgba<u8>),
#[from]
#[display(fmt = "{}", "display_rgb_u8(_0)")]
RgbU8(Srgb<u8>),
#[display(fmt = "transparent")]
Transparent,
#[display(fmt = "currentColor")]
CurrentColor,
}
impl From<Packed> for Color {
fn from(source: Packed) -> Self {
Color::RgbaU8(source.into())
}
}
impl From<u32> for Color {
fn from(source: u32) -> Self {
Color::from(Packed::from(source))
}
}
impl From<(u8, u8, u8)> for Color {
fn from(source: (u8, u8, u8)) -> Self {
Color::RgbU8(source.into())
}
}
impl From<(u8, u8, u8, u8)> for Color {
fn from(source: (u8, u8, u8, u8)) -> Self {
Color::RgbaU8(source.into())
}
}
impl From<(f32, f32, f32)> for Color {
fn from(source: (f32, f32, f32)) -> Self {
Color::Rgb(source.into())
}
}
impl From<(f32, f32, f32, f32)> for Color {
fn from(source: (f32, f32, f32, f32)) -> Self {
Color::Rgba(source.into())
}
}
impl<T> FromColor<T> for Color
where
T: IntoColor<Srgba>,
{
fn from_color(t: T) -> Self {
let rgba = t.into_color();
Color::Rgba(rgba)
}
}
impl StyleUpdater for Color {
fn update_style(self, style: Style) -> Style {
style.insert("color", self)
}
}
#[derive(Clone, Copy, Debug, PartialEq, From)]
pub struct Opacity(f32);
impl StyleUpdater for Opacity {
fn update_style(self, style: Style) -> Style {
style.insert("opacity", self.0)
}
}
impl TryFrom<Color> for Srgba {
type Error = &'static str;
fn try_from(value: Color) -> Result<Self, Self::Error> {
match value {
Color::Rgb(rgb) => Ok(rgb.into()),
Color::Rgba(rgba) => Ok(rgba),
Color::RgbaU8(rgb) => Ok(rgb.into_format()),
Color::RgbU8(rgb) => Ok(rgb.into_format().into()),
Color::Transparent => Ok(Srgba::new(0.0, 0.0, 0.0, 0.0)),
Color::CurrentColor => Err("Cannot convert CurrentColor into a color"),
}
}
}
impl TryFrom<Color> for Srgb {
type Error = &'static str;
fn try_from(value: Color) -> Result<Self, Self::Error> {
let rgba: Srgba = value.try_into()?;
Ok(rgba.color)
}
}