diff --git a/src/color/mod.rs b/src/color/mod.rs index 2df8d69..9de0297 100644 --- a/src/color/mod.rs +++ b/src/color/mod.rs @@ -18,6 +18,7 @@ use std::{ cmp::{max, min}, fmt::{self, Display}, + hash::{Hash, Hasher}, }; use crate::value::Number; @@ -27,13 +28,27 @@ use num_traits::{One, Signed, ToPrimitive, Zero}; mod name; -#[derive(Debug, Clone, Eq, PartialEq, Hash)] +#[derive(Debug, Clone)] pub(crate) struct Color { rgba: Rgba, hsla: Option, repr: String, } +impl PartialEq for Color { + fn eq(&self, other: &Self) -> bool { + self.rgba == other.rgba + } +} + +impl Eq for Color {} + +impl Hash for Color { + fn hash(&self, state: &mut H) { + self.rgba.hash(state) + } +} + impl Color { pub const fn new_rgba( red: Number, @@ -65,7 +80,7 @@ impl Color { } } -#[derive(Debug, Clone, Eq, PartialEq, Hash)] +#[derive(Debug, Clone)] struct Rgba { red: Number, green: Number, @@ -73,6 +88,62 @@ struct Rgba { alpha: Number, } +impl PartialEq for Rgba { + fn eq(&self, other: &Self) -> bool { + if self.red != other.red + && !(self.red >= Number::from(255) && other.red >= Number::from(255)) + { + return false; + } + if self.green != other.green + && !(self.green >= Number::from(255) && other.green >= Number::from(255)) + { + return false; + } + if self.blue != other.blue + && !(self.blue >= Number::from(255) && other.blue >= Number::from(255)) + { + return false; + } + if self.alpha != other.alpha + && !(self.alpha >= Number::one() && other.alpha >= Number::one()) + { + return false; + } + true + } +} + +impl Eq for Rgba {} + +impl Hash for Rgba { + fn hash(&self, state: &mut H) { + if self.red > Number::from(255) { + 255.hash(state); + } else { + self.red.hash(state) + } + + if self.green > Number::from(255) { + 255.hash(state); + } else { + self.green.hash(state) + } + + if self.blue > Number::from(255) { + 255.hash(state); + } else { + self.blue.hash(state) + } + + if self.alpha > Number::one() { + 1.hash(state); + } else { + self.alpha.hash(state) + } + } +} + impl Rgba { pub const fn new(red: Number, green: Number, blue: Number, alpha: Number) -> Self { Rgba { @@ -88,7 +159,7 @@ impl Rgba { } } -#[derive(Debug, Clone, Eq, PartialEq, Hash)] +#[derive(Debug, Clone)] struct Hsla { hue: Number, saturation: Number, diff --git a/tests/color.rs b/tests/color.rs index f29ec23..3d32932 100644 --- a/tests/color.rs +++ b/tests/color.rs @@ -623,3 +623,13 @@ test!( "a {\n color: blue(rgba(1.5, 1.5, 1.5, 1));\n}\n", "a {\n color: 2;\n}\n" ); +test!( + color_equality_named_and_hex, + "a {\n color: red==#ff0000;\n}\n", + "a {\n color: true;\n}\n" +); +test!( + color_equality_named_and_hsla, + "a {\n color: hsla(0deg, 100%, 50%)==red;\n}\n", + "a {\n color: true;\n}\n" +);