1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
use crate::float::Float;
use crate::white_point::WhitePoint;
use crate::{
from_f64, FloatComponent, FromF64, Hsluv, Lab, LabHue, Lch, Lchuv, Luv, LuvHue, OklabHue,
RgbHue, Xyz, Yxy,
};
macro_rules! impl_eq {
( $self_ty: ident , [$($element: ident),+]) => {
impl<Wp, T> AbsDiffEq for $self_ty<Wp, T>
where T: FloatComponent + AbsDiffEq,
T::Epsilon: Copy + FloatComponent,
Wp: WhitePoint + PartialEq
{
type Epsilon = T::Epsilon;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
}
fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
$( self.$element.abs_diff_eq(&other.$element, epsilon) )&&+
}
fn abs_diff_ne(&self, other: &Self, epsilon: T::Epsilon) -> bool {
$( self.$element.abs_diff_ne(&other.$element, epsilon) )||+
}
}
impl<Wp, T> RelativeEq for $self_ty<Wp, T>
where T: FloatComponent + RelativeEq,
T::Epsilon: Copy + FloatComponent,
Wp: WhitePoint + PartialEq
{
fn default_max_relative() -> T::Epsilon {
T::default_max_relative()
}
fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
$( self.$element.relative_eq(&other.$element, epsilon, max_relative) )&&+
}
fn relative_ne(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
$( self.$element.relative_ne(&other.$element, epsilon, max_relative) )||+
}
}
impl<Wp, T> UlpsEq for $self_ty<Wp, T>
where T: FloatComponent + UlpsEq,
T::Epsilon: Copy + FloatComponent,
Wp: WhitePoint + PartialEq
{
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
$( self.$element.ulps_eq(&other.$element, epsilon, max_ulps) )&&+
}
fn ulps_ne(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
$( self.$element.ulps_ne(&other.$element, epsilon, max_ulps) )||+
}
}
}
}
impl_eq!(Xyz, [x, y, z]);
impl_eq!(Yxy, [y, x, luma]);
impl_eq!(Lab, [l, a, b]);
impl_eq!(Luv, [l, u, v]);
impl_eq!(Lch, [l, chroma, hue]);
impl_eq!(Lchuv, [l, chroma, hue]);
impl_eq!(Hsluv, [hue, saturation, l]);
macro_rules! impl_eq_hue {
( $self_ty: ident ) => {
impl<T: Float + FromF64 + AbsDiffEq> AbsDiffEq for $self_ty<T>
where
T::Epsilon: Float + FromF64,
{
type Epsilon = T::Epsilon;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon() * from_f64(180.0)
}
fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
let diff: T = (*self - *other).to_degrees();
T::abs_diff_eq(&diff, &T::zero(), epsilon)
}
fn abs_diff_ne(&self, other: &Self, epsilon: T::Epsilon) -> bool {
let diff: T = (*self - *other).to_degrees();
T::abs_diff_ne(&diff, &T::zero(), epsilon)
}
}
impl<T: Float + FromF64 + RelativeEq> RelativeEq for $self_ty<T>
where
T::Epsilon: Float + FromF64,
{
fn default_max_relative() -> Self::Epsilon {
T::default_max_relative() * from_f64(180.0)
}
fn relative_eq(
&self,
other: &Self,
epsilon: T::Epsilon,
max_relative: T::Epsilon,
) -> bool {
let diff: T = (*self - *other).to_degrees();
T::relative_eq(&diff, &T::zero(), epsilon, max_relative)
}
fn relative_ne(
&self,
other: &Self,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
let diff: T = (*self - *other).to_degrees();
T::relative_ne(&diff, &T::zero(), epsilon, max_relative)
}
}
impl<T: Float + FromF64 + UlpsEq> UlpsEq for $self_ty<T>
where
T::Epsilon: Float + FromF64,
{
fn default_max_ulps() -> u32 {
T::default_max_ulps() * 180
}
fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
let diff: T = (*self - *other).to_degrees();
T::ulps_eq(&diff, &T::zero(), epsilon, max_ulps)
}
fn ulps_ne(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
let diff: T = (*self - *other).to_degrees();
T::ulps_ne(&diff, &T::zero(), epsilon, max_ulps)
}
}
};
}
impl_eq_hue!(LabHue);
impl_eq_hue!(RgbHue);
impl_eq_hue!(LuvHue);
impl_eq_hue!(OklabHue);