Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement PartialEq/Eq for all colorspaces, Alpha, PreAlpha, and LabHue/RgbHue #211

Merged
merged 3 commits into from Apr 5, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 21 additions & 4 deletions palette/src/alpha/alpha.rs
Expand Up @@ -19,7 +19,7 @@ use crate::{
};

/// An alpha component wrapper for colors.
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))]
#[repr(C)]
pub struct Alpha<C, T> {
Expand All @@ -44,6 +44,23 @@ impl<C, T: Component> Alpha<C, T> {
}
}

impl<C, T> PartialEq for Alpha<C, T>
where
T: Component + PartialEq,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I bet the Component here is what makes it require them for the other comparison traits. It shouldn't be necessary here and for Eq. 🙂

C: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.color == other.color && self.alpha == other.alpha
}
}

impl<C, T> Eq for Alpha<C, T>
where
T: Component + Eq,
C: Eq,
{
}

impl<C1: WithAlpha<T>, C2, T: Component> FromColorUnclamped<C1> for Alpha<C2, T>
where
C1::Color: IntoColorUnclamped<C2>,
Expand Down Expand Up @@ -215,7 +232,7 @@ impl<C: Default, T: Component> Default for Alpha<C, T> {
impl<C, T> AbsDiffEq for Alpha<C, T>
where
C: AbsDiffEq<Epsilon = T::Epsilon>,
T: AbsDiffEq,
T: AbsDiffEq + Component,
T::Epsilon: Clone,
{
type Epsilon = T::Epsilon;
Expand All @@ -233,7 +250,7 @@ where
impl<C, T> RelativeEq for Alpha<C, T>
where
C: RelativeEq<Epsilon = T::Epsilon>,
T: RelativeEq,
T: RelativeEq + Component,
T::Epsilon: Clone,
{
fn default_max_relative() -> Self::Epsilon {
Expand All @@ -255,7 +272,7 @@ where
impl<C, T> UlpsEq for Alpha<C, T>
where
C: UlpsEq<Epsilon = T::Epsilon>,
T: UlpsEq,
T: UlpsEq + Component,
T::Epsilon: Clone,
{
fn default_max_ulps() -> u32 {
Expand Down
19 changes: 18 additions & 1 deletion palette/src/blend/pre_alpha.rs
Expand Up @@ -27,7 +27,7 @@ use crate::{clamp, Alpha, Blend, ComponentWise, Mix, Pixel};
///
/// Note that converting to and from premultiplied alpha will cause the alpha
/// component to be clamped to [0.0, 1.0].
#[derive(Clone, Copy, PartialEq, Debug)]
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))]
#[repr(C)]
pub struct PreAlpha<C, T: Float> {
Expand All @@ -40,6 +40,23 @@ pub struct PreAlpha<C, T: Float> {
pub alpha: T,
}

impl<C, T> PartialEq for PreAlpha<C, T>
where
T: Float + PartialEq,
C: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.color == other.color && self.alpha == other.alpha
}
}

impl<C, T> Eq for PreAlpha<C, T>
where
T: Float + Eq,
C: Eq,
{
}

impl<C, T> From<Alpha<C, T>> for PreAlpha<C, T>
where
C: ComponentWise<Scalar = T>,
Expand Down
19 changes: 18 additions & 1 deletion palette/src/hsl.rs
Expand Up @@ -35,7 +35,7 @@ pub type Hsla<S = Srgb, T = f32> = Alpha<Hsl<S, T>, T>;
///
/// See [HSV](crate::Hsv) for a very similar color space, with brightness
/// instead of lightness.
#[derive(Debug, PartialEq, Pixel, FromColorUnclamped, WithAlpha)]
#[derive(Debug, Pixel, FromColorUnclamped, WithAlpha)]
#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))]
#[palette(
palette_internal,
Expand Down Expand Up @@ -158,6 +158,23 @@ where
}
}

impl<S, T> PartialEq for Hsl<S, T>
where
T: FloatComponent + PartialEq,
S: RgbStandard,
{
fn eq(&self, other: &Self) -> bool {
self.hue == other.hue && self.saturation == other.saturation && self.lightness == other.lightness
}
}

impl<S, T> Eq for Hsl<S, T>
where
T: FloatComponent + Eq,
S: RgbStandard,
{
}

///<span id="Hsla"></span>[`Hsla`](crate::Hsla) implementations.
impl<T, A> Alpha<Hsl<Srgb, T>, A>
where
Expand Down
19 changes: 18 additions & 1 deletion palette/src/hsv.rs
Expand Up @@ -32,7 +32,7 @@ pub type Hsva<S = Srgb, T = f32> = Alpha<Hsv<S, T>, T>;
/// _lightness_. The difference is that, for example, red (100% R, 0% G, 0% B)
/// and white (100% R, 100% G, 100% B) has the same brightness (or value), but
/// not the same lightness.
#[derive(Debug, PartialEq, Pixel, FromColorUnclamped, WithAlpha)]
#[derive(Debug, Pixel, FromColorUnclamped, WithAlpha)]
#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))]
#[palette(
palette_internal,
Expand Down Expand Up @@ -155,6 +155,23 @@ where
}
}

impl<S, T> PartialEq for Hsv<S, T>
where
T: FloatComponent + PartialEq,
S: RgbStandard,
{
fn eq(&self, other: &Self) -> bool {
self.hue == other.hue && self.saturation == other.saturation && self.value == other.value
}
}

impl<S, T> Eq for Hsv<S, T>
where
T: FloatComponent + Eq,
S: RgbStandard,
{
}

///<span id="Hsva"></span>[`Hsva`](crate::Hsva) implementations.
impl<T, A> Alpha<Hsv<Srgb, T>, A>
where
Expand Down
2 changes: 2 additions & 0 deletions palette/src/hues.rs
Expand Up @@ -119,6 +119,8 @@ macro_rules! make_hues {
}
}

impl<T: Float + FromF64 + Eq> Eq for $name<T> {}

impl<T: Float> Add<$name<T>> for $name<T> {
type Output = $name<T>;

Expand Down
21 changes: 20 additions & 1 deletion palette/src/hwb.rs
Expand Up @@ -33,7 +33,7 @@ pub type Hwba<S = Srgb, T = f32> = Alpha<Hwb<S, T>, T>;
///
/// It is very intuitive for humans to use and many color-pickers are based on
/// the HWB color system
#[derive(Debug, PartialEq, Pixel, FromColorUnclamped, WithAlpha)]
#[derive(Debug, Pixel, FromColorUnclamped, WithAlpha)]
#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))]
#[palette(
palette_internal,
Expand Down Expand Up @@ -161,6 +161,25 @@ where
}
}

impl<S, T> PartialEq for Hwb<S, T>
where
T: FloatComponent + PartialEq,
S: RgbStandard,
{
fn eq(&self, other: &Self) -> bool {
self.hue == other.hue
&& self.whiteness == other.whiteness
&& self.blackness == other.blackness
}
}

impl<S, T> Eq for Hwb<S, T>
where
T: FloatComponent + Eq,
S: RgbStandard,
{
}

///<span id="Hwba"></span>[`Hwba`](crate::Hwba) implementations.
impl<T, A> Alpha<Hwb<Srgb, T>, A>
where
Expand Down
19 changes: 18 additions & 1 deletion palette/src/lab.rs
Expand Up @@ -33,7 +33,7 @@ pub type Laba<Wp = D65, T = f32> = Alpha<Lab<Wp, T>, T>;
///
/// The parameters of L\*a\*b\* are quite different, compared to many other
/// color spaces, so manipulating them manually may be unintuitive.
#[derive(Debug, PartialEq, Pixel, FromColorUnclamped, WithAlpha)]
#[derive(Debug, Pixel, FromColorUnclamped, WithAlpha)]
#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))]
#[palette(
palette_internal,
Expand Down Expand Up @@ -152,6 +152,23 @@ where
}
}

impl<Wp, T> PartialEq for Lab<Wp, T>
where
T: FloatComponent + PartialEq,
Wp: WhitePoint,
{
fn eq(&self, other: &Self) -> bool {
self.l == other.l && self.a == other.a && self.b == other.b
}
}

impl<Wp, T> Eq for Lab<Wp, T>
where
T: FloatComponent + Eq,
Wp: WhitePoint,
{
}

///<span id="Laba"></span>[`Laba`](crate::Laba) implementations.
impl<T, A> Alpha<Lab<D65, T>, A>
where
Expand Down
19 changes: 18 additions & 1 deletion palette/src/lch.rs
Expand Up @@ -28,7 +28,7 @@ pub type Lcha<Wp = D65, T = f32> = Alpha<Lch<Wp, T>, T>;
/// it's a cylindrical color space, like [HSL](crate::Hsl) and
/// [HSV](crate::Hsv). This gives it the same ability to directly change
/// the hue and colorfulness of a color, while preserving other visual aspects.
#[derive(Debug, PartialEq, Pixel, FromColorUnclamped, WithAlpha)]
#[derive(Debug, Pixel, FromColorUnclamped, WithAlpha)]
#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))]
#[palette(
palette_internal,
Expand Down Expand Up @@ -151,6 +151,23 @@ where
}
}

impl<Wp, T> PartialEq for Lch<Wp, T>
where
T: FloatComponent + PartialEq,
Wp: WhitePoint,
{
fn eq(&self, other: &Self) -> bool {
self.l == other.l && self.chroma == other.chroma && self.hue == other.hue
}
}

impl<Wp, T> Eq for Lch<Wp, T>
where
T: FloatComponent + Eq,
Wp: WhitePoint,
{
}

///<span id="Lcha"></span>[`Lcha`](crate::Lcha) implementations.
impl<T, A> Alpha<Lch<D65, T>, A>
where
Expand Down
19 changes: 18 additions & 1 deletion palette/src/luma/luma.rs
Expand Up @@ -33,7 +33,7 @@ pub type Lumaa<S = Srgb, T = f32> = Alpha<Luma<S, T>, T>;
/// perceived to be. It's basically the `Y` component of [CIE
/// XYZ](crate::Xyz). The lack of any form of hue representation limits
/// the set of operations that can be performed on it.
#[derive(Debug, PartialEq, Pixel, FromColorUnclamped, WithAlpha)]
#[derive(Debug, Pixel, FromColorUnclamped, WithAlpha)]
#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))]
#[palette(
palette_internal,
Expand Down Expand Up @@ -166,6 +166,23 @@ where
}
}

impl<S, T> PartialEq for Luma<S, T>
where
T: Component + PartialEq,
S: LumaStandard,
{
fn eq(&self, other: &Self) -> bool {
self.luma == other.luma
}
}

impl<S, T> Eq for Luma<S, T>
where
T: Component + Eq,
S: LumaStandard,
{
}

///<span id="Lumaa"></span>[`Lumaa`](crate::luma::Lumaa) implementations.
impl<S, T, A> Alpha<Luma<S, T>, A>
where
Expand Down
19 changes: 18 additions & 1 deletion palette/src/rgb/rgb.rs
Expand Up @@ -43,7 +43,7 @@ pub type Rgba<S = Srgb, T = f32> = Alpha<Rgb<S, T>, T>;
/// linear, meaning that gamma correction is required when converting to and
/// from a displayable RGB, such as sRGB. See the [`pixel`](crate::encoding::pixel)
/// module for encoding formats.
#[derive(Debug, PartialEq, Pixel, FromColorUnclamped, WithAlpha)]
#[derive(Debug, Pixel, FromColorUnclamped, WithAlpha)]
#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))]
#[palette(
palette_internal,
Expand Down Expand Up @@ -154,6 +154,23 @@ impl<S: RgbStandard, T: Component> Rgb<S, T> {
}
}

impl<S, T> PartialEq for Rgb<S, T>
where
T: Component + PartialEq,
S: RgbStandard,
{
fn eq(&self, other: &Self) -> bool {
self.red == other.red && self.green == other.green && self.blue == other.blue
}
}

impl<S, T> Eq for Rgb<S, T>
where
T: Component + Eq,
S: RgbStandard,
{
}

/// Convenience functions to convert between a packed `u32` and `Rgb`.
///
/// ```
Expand Down
19 changes: 18 additions & 1 deletion palette/src/xyz.rs
Expand Up @@ -32,7 +32,7 @@ pub type Xyza<Wp = D65, T = f32> = Alpha<Xyz<Wp, T>, T>;
///
/// Conversions and operations on this color space depend on the defined white
/// point
#[derive(Debug, PartialEq, Pixel, FromColorUnclamped, WithAlpha)]
#[derive(Debug, Pixel, FromColorUnclamped, WithAlpha)]
#[cfg_attr(feature = "serializing", derive(Serialize, Deserialize))]
#[palette(
palette_internal,
Expand Down Expand Up @@ -157,6 +157,23 @@ where
}
}

impl<Wp, T> PartialEq for Xyz<Wp, T>
where
T: FloatComponent + PartialEq,
Wp: WhitePoint,
{
fn eq(&self, other: &Self) -> bool {
self.x == other.x && self.y == other.y && self.z == other.z
}
}

impl<Wp, T> Eq for Xyz<Wp, T>
where
T: FloatComponent + Eq,
Wp: WhitePoint,
{
}

///<span id="Xyza"></span>[`Xyza`](crate::Xyza) implementations.
impl<T, A> Alpha<Xyz<D65, T>, A>
where
Expand Down