use crate::spaces::{
Cubehelix, Dlab, Dlch, Hpluv, Hsi, Hsl, Hsluv, Hsv, Hwb, Itp, Jab, Jch, Lab, Lab65, Lch, Lch65,
Lchuv, LinearRgb, Luv, Okhsl, Okhsv, Oklab, Oklch, Prismatic, ProphotoRgb, Rec2020, Rgb, Xyb,
Xyz50, Xyz65, Yiq, A98, P3,
};
use crate::traits::ColorSpace;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Color {
Rgb(Rgb),
LinearRgb(LinearRgb),
Hsl(Hsl),
Hsv(Hsv),
Hwb(Hwb),
Lab(Lab),
Lab65(Lab65),
Lch(Lch),
Lch65(Lch65),
Oklab(Oklab),
Oklch(Oklch),
Xyz50(Xyz50),
Xyz65(Xyz65),
P3(P3),
Rec2020(Rec2020),
A98(A98),
ProphotoRgb(ProphotoRgb),
Cubehelix(Cubehelix),
Dlab(Dlab),
Dlch(Dlch),
Jab(Jab),
Jch(Jch),
Yiq(Yiq),
Hsi(Hsi),
Hsluv(Hsluv),
Hpluv(Hpluv),
Okhsl(Okhsl),
Okhsv(Okhsv),
Itp(Itp),
Xyb(Xyb),
Luv(Luv),
Lchuv(Lchuv),
Prismatic(Prismatic),
}
impl From<Rgb> for Color {
fn from(c: Rgb) -> Self {
Color::Rgb(c)
}
}
impl From<LinearRgb> for Color {
fn from(c: LinearRgb) -> Self {
Color::LinearRgb(c)
}
}
impl From<Hsl> for Color {
fn from(c: Hsl) -> Self {
Color::Hsl(c)
}
}
impl From<Hsv> for Color {
fn from(c: Hsv) -> Self {
Color::Hsv(c)
}
}
impl From<Hwb> for Color {
fn from(c: Hwb) -> Self {
Color::Hwb(c)
}
}
impl From<Lab> for Color {
fn from(c: Lab) -> Self {
Color::Lab(c)
}
}
impl From<Lab65> for Color {
fn from(c: Lab65) -> Self {
Color::Lab65(c)
}
}
impl From<Lch> for Color {
fn from(c: Lch) -> Self {
Color::Lch(c)
}
}
impl From<Lch65> for Color {
fn from(c: Lch65) -> Self {
Color::Lch65(c)
}
}
impl From<Oklab> for Color {
fn from(c: Oklab) -> Self {
Color::Oklab(c)
}
}
impl From<Oklch> for Color {
fn from(c: Oklch) -> Self {
Color::Oklch(c)
}
}
impl From<Xyz50> for Color {
fn from(c: Xyz50) -> Self {
Color::Xyz50(c)
}
}
impl From<Xyz65> for Color {
fn from(c: Xyz65) -> Self {
Color::Xyz65(c)
}
}
impl From<P3> for Color {
fn from(c: P3) -> Self {
Color::P3(c)
}
}
impl From<Rec2020> for Color {
fn from(c: Rec2020) -> Self {
Color::Rec2020(c)
}
}
impl From<A98> for Color {
fn from(c: A98) -> Self {
Color::A98(c)
}
}
impl From<ProphotoRgb> for Color {
fn from(c: ProphotoRgb) -> Self {
Color::ProphotoRgb(c)
}
}
impl From<Cubehelix> for Color {
fn from(c: Cubehelix) -> Self {
Color::Cubehelix(c)
}
}
impl From<Dlab> for Color {
fn from(c: Dlab) -> Self {
Color::Dlab(c)
}
}
impl From<Dlch> for Color {
fn from(c: Dlch) -> Self {
Color::Dlch(c)
}
}
impl From<Jab> for Color {
fn from(c: Jab) -> Self {
Color::Jab(c)
}
}
impl From<Jch> for Color {
fn from(c: Jch) -> Self {
Color::Jch(c)
}
}
impl From<Yiq> for Color {
fn from(c: Yiq) -> Self {
Color::Yiq(c)
}
}
impl From<Hsi> for Color {
fn from(c: Hsi) -> Self {
Color::Hsi(c)
}
}
impl From<Hsluv> for Color {
fn from(c: Hsluv) -> Self {
Color::Hsluv(c)
}
}
impl From<Hpluv> for Color {
fn from(c: Hpluv) -> Self {
Color::Hpluv(c)
}
}
impl From<Okhsl> for Color {
fn from(c: Okhsl) -> Self {
Color::Okhsl(c)
}
}
impl From<Okhsv> for Color {
fn from(c: Okhsv) -> Self {
Color::Okhsv(c)
}
}
impl From<Itp> for Color {
fn from(c: Itp) -> Self {
Color::Itp(c)
}
}
impl From<Xyb> for Color {
fn from(c: Xyb) -> Self {
Color::Xyb(c)
}
}
impl From<Luv> for Color {
fn from(c: Luv) -> Self {
Color::Luv(c)
}
}
impl From<Lchuv> for Color {
fn from(c: Lchuv) -> Self {
Color::Lchuv(c)
}
}
impl From<Prismatic> for Color {
fn from(c: Prismatic) -> Self {
Color::Prismatic(c)
}
}
impl Color {
pub fn mode(&self) -> &'static str {
match self {
Color::Rgb(_) => Rgb::MODE,
Color::LinearRgb(_) => LinearRgb::MODE,
Color::Hsl(_) => Hsl::MODE,
Color::Hsv(_) => Hsv::MODE,
Color::Hwb(_) => Hwb::MODE,
Color::Lab(_) => Lab::MODE,
Color::Lab65(_) => Lab65::MODE,
Color::Lch(_) => Lch::MODE,
Color::Lch65(_) => Lch65::MODE,
Color::Oklab(_) => Oklab::MODE,
Color::Oklch(_) => Oklch::MODE,
Color::Xyz50(_) => Xyz50::MODE,
Color::Xyz65(_) => Xyz65::MODE,
Color::P3(_) => P3::MODE,
Color::Rec2020(_) => Rec2020::MODE,
Color::A98(_) => A98::MODE,
Color::ProphotoRgb(_) => ProphotoRgb::MODE,
Color::Cubehelix(_) => Cubehelix::MODE,
Color::Dlab(_) => Dlab::MODE,
Color::Dlch(_) => Dlch::MODE,
Color::Jab(_) => Jab::MODE,
Color::Jch(_) => Jch::MODE,
Color::Yiq(_) => Yiq::MODE,
Color::Hsi(_) => Hsi::MODE,
Color::Hsluv(_) => Hsluv::MODE,
Color::Hpluv(_) => Hpluv::MODE,
Color::Okhsl(_) => Okhsl::MODE,
Color::Okhsv(_) => Okhsv::MODE,
Color::Itp(_) => Itp::MODE,
Color::Xyb(_) => Xyb::MODE,
Color::Luv(_) => Luv::MODE,
Color::Lchuv(_) => Lchuv::MODE,
Color::Prismatic(_) => Prismatic::MODE,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ColorVariantMismatch {
pub expected: &'static str,
pub actual: &'static str,
}
impl core::fmt::Display for ColorVariantMismatch {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"Color variant mismatch: expected `{}`, found `{}`",
self.expected, self.actual
)
}
}
impl std::error::Error for ColorVariantMismatch {}
macro_rules! impl_try_from_color {
($($variant:ident => $ty:ty),* $(,)?) => {
$(
impl TryFrom<Color> for $ty {
type Error = ColorVariantMismatch;
fn try_from(c: Color) -> Result<Self, Self::Error> {
match c {
Color::$variant(inner) => Ok(inner),
other => Err(ColorVariantMismatch {
expected: <$ty>::MODE,
actual: other.mode(),
}),
}
}
}
)*
};
}
impl_try_from_color! {
Rgb => Rgb,
LinearRgb => LinearRgb,
Hsl => Hsl,
Hsv => Hsv,
Hwb => Hwb,
Lab => Lab,
Lab65 => Lab65,
Lch => Lch,
Lch65 => Lch65,
Oklab => Oklab,
Oklch => Oklch,
Xyz50 => Xyz50,
Xyz65 => Xyz65,
P3 => P3,
Rec2020 => Rec2020,
A98 => A98,
ProphotoRgb => ProphotoRgb,
Cubehelix => Cubehelix,
Dlab => Dlab,
Dlch => Dlch,
Jab => Jab,
Jch => Jch,
Yiq => Yiq,
Hsi => Hsi,
Hsluv => Hsluv,
Hpluv => Hpluv,
Okhsl => Okhsl,
Okhsv => Okhsv,
Itp => Itp,
Xyb => Xyb,
Luv => Luv,
Lchuv => Lchuv,
Prismatic => Prismatic,
}