Skip to content

Commit a0110d5

Browse files
bors[bot]Finomnis
andauthored
Merge #323
323: Add saturating_add and saturating_sub for integer based colors r=Ogeon a=Finomnis - Add `crate::num::SaturatingAdd` and `crate::num::SaturatingSub` traits - Implement them for all unsigned integers - Implement them for unsigned integer based hues - Implement them for unsigned integer based colors - Implement them for unsigned integer based alpha Example: ```rust use palette::{ num::{SaturatingAdd, SaturatingSub}, Srgb, }; fn main() { let color1 = Srgb::<u8>::new(200, 20, 20); let color2 = Srgb::<u8>::new(100, 10, 10); let color_sum = color1.saturating_add(color2); println!("{:?}", color_sum); let color_diff = color2.saturating_sub(30); println!("{:?}", color_diff); } ``` ``` Rgb { red: 255, green: 30, blue: 30, standard: PhantomData<palette::encoding::srgb::Srgb> } Rgb { red: 70, green: 0, blue: 0, standard: PhantomData<palette::encoding::srgb::Srgb> } ``` ## Closed Issues * Closes #322, by implementing the proposed functionality. Co-authored-by: Finomnis <finomnis@gmail.com>
2 parents eb51f14 + e0917f0 commit a0110d5

File tree

4 files changed

+243
-3
lines changed

4 files changed

+243
-3
lines changed

palette/src/alpha/alpha.rs

+61-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
cast::ArrayCast,
2323
clamp, clamp_assign,
2424
convert::{FromColorUnclamped, IntoColorUnclamped},
25-
num::{self, Arithmetics, One, PartialCmp, Zero},
25+
num::{self, Arithmetics, One, PartialCmp, SaturatingAdd, SaturatingSub, Zero},
2626
stimulus::Stimulus,
2727
ArrayExt, Clamp, ClampAssign, GetHue, IsWithinBounds, Lighten, LightenAssign, Mix, MixAssign,
2828
NextArray, Saturate, SaturateAssign, SetHue, ShiftHue, ShiftHueAssign, WithAlpha, WithHue,
@@ -455,6 +455,36 @@ where
455455
}
456456
}
457457

458+
impl<C, T> SaturatingAdd for Alpha<C, T>
459+
where
460+
C: SaturatingAdd,
461+
T: SaturatingAdd,
462+
{
463+
type Output = Alpha<C::Output, <T as SaturatingAdd>::Output>;
464+
465+
fn saturating_add(self, other: Alpha<C, T>) -> Self::Output {
466+
Alpha {
467+
color: self.color.saturating_add(other.color),
468+
alpha: self.alpha.saturating_add(other.alpha),
469+
}
470+
}
471+
}
472+
473+
impl<T, C> SaturatingAdd<T> for Alpha<C, T>
474+
where
475+
T: SaturatingAdd + Clone,
476+
C: SaturatingAdd<T>,
477+
{
478+
type Output = Alpha<C::Output, <T as SaturatingAdd>::Output>;
479+
480+
fn saturating_add(self, c: T) -> Self::Output {
481+
Alpha {
482+
color: self.color.saturating_add(c.clone()),
483+
alpha: self.alpha.saturating_add(c),
484+
}
485+
}
486+
}
487+
458488
impl<C, T> Sub for Alpha<C, T>
459489
where
460490
C: Sub,
@@ -507,6 +537,36 @@ where
507537
}
508538
}
509539

540+
impl<C, T> SaturatingSub for Alpha<C, T>
541+
where
542+
C: SaturatingSub,
543+
T: SaturatingSub,
544+
{
545+
type Output = Alpha<C::Output, <T as SaturatingSub>::Output>;
546+
547+
fn saturating_sub(self, other: Alpha<C, T>) -> Self::Output {
548+
Alpha {
549+
color: self.color.saturating_sub(other.color),
550+
alpha: self.alpha.saturating_sub(other.alpha),
551+
}
552+
}
553+
}
554+
555+
impl<T, C> SaturatingSub<T> for Alpha<C, T>
556+
where
557+
T: SaturatingSub + Clone,
558+
C: SaturatingSub<T>,
559+
{
560+
type Output = Alpha<C::Output, <T as SaturatingSub>::Output>;
561+
562+
fn saturating_sub(self, c: T) -> Self::Output {
563+
Alpha {
564+
color: self.color.saturating_sub(c.clone()),
565+
alpha: self.alpha.saturating_sub(c),
566+
}
567+
}
568+
}
569+
510570
impl<C, T> Mul for Alpha<C, T>
511571
where
512572
C: Mul,

palette/src/hues.rs

+36
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,24 @@ macro_rules! make_hues {
347347
}
348348
}
349349

350+
impl<T: $crate::num::SaturatingAdd<Output=T>> $crate::num::SaturatingAdd<$name<T>> for $name<T> {
351+
type Output = $name<T>;
352+
353+
#[inline]
354+
fn saturating_add(self, other: $name<T>) -> $name<T> {
355+
$name(self.0.saturating_add(other.0))
356+
}
357+
}
358+
359+
impl<T: $crate::num::SaturatingAdd<Output=T>> $crate::num::SaturatingAdd<T> for $name<T> {
360+
type Output = $name<T>;
361+
362+
#[inline]
363+
fn saturating_add(self, other: T) -> $name<T> {
364+
$name(self.0.saturating_add(other))
365+
}
366+
}
367+
350368
impl<T: Sub<Output=T>> Sub<$name<T>> for $name<T> {
351369
type Output = $name<T>;
352370

@@ -411,6 +429,24 @@ macro_rules! make_hues {
411429
}
412430
}
413431

432+
impl<T: $crate::num::SaturatingSub<Output=T>> $crate::num::SaturatingSub<$name<T>> for $name<T> {
433+
type Output = $name<T>;
434+
435+
#[inline]
436+
fn saturating_sub(self, other: $name<T>) -> $name<T> {
437+
$name(self.0.saturating_sub(other.0))
438+
}
439+
}
440+
441+
impl<T: $crate::num::SaturatingSub<Output=T>> $crate::num::SaturatingSub<T> for $name<T> {
442+
type Output = $name<T>;
443+
444+
#[inline]
445+
fn saturating_sub(self, other: T) -> $name<T> {
446+
$name(self.0.saturating_sub(other))
447+
}
448+
}
449+
414450
#[cfg(feature = "random")]
415451
impl<T> Distribution<$name<T>> for Standard
416452
where

palette/src/macros/arithmetics.rs

+110-2
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,40 @@ macro_rules! impl_color_add {
3939

4040
impl<$phantom_ty, $component_ty> AddAssign<$component_ty> for $self_ty<$phantom_ty, $component_ty>
4141
where
42-
T: AddAssign + Clone
42+
T: AddAssign + Clone
4343
{
4444
fn add_assign(&mut self, c: $component_ty) {
4545
$( self.$element += c.clone(); )+
4646
}
4747
}
48+
49+
impl<$phantom_ty, $component_ty> $crate::num::SaturatingAdd<Self> for $self_ty<$phantom_ty, $component_ty>
50+
where
51+
T: $crate::num::SaturatingAdd<Output=$component_ty>
52+
{
53+
type Output = Self;
54+
55+
fn saturating_add(self, other: Self) -> Self::Output {
56+
$self_ty {
57+
$( $element: self.$element.saturating_add(other.$element), )+
58+
$phantom: PhantomData,
59+
}
60+
}
61+
}
62+
63+
impl<$phantom_ty, $component_ty> $crate::num::SaturatingAdd<$component_ty> for $self_ty<$phantom_ty, $component_ty>
64+
where
65+
T: $crate::num::SaturatingAdd<Output=$component_ty> + Clone
66+
{
67+
type Output = Self;
68+
69+
fn saturating_add(self, c: $component_ty) -> Self::Output {
70+
$self_ty {
71+
$( $element: self.$element.saturating_add(c.clone()), )+
72+
$phantom: PhantomData,
73+
}
74+
}
75+
}
4876
};
4977
($self_ty: ident < $component_ty: ident > , [$($element: ident),+]) => {
5078
impl<$component_ty> Add<Self> for $self_ty<$component_ty>
@@ -84,12 +112,38 @@ macro_rules! impl_color_add {
84112

85113
impl<$component_ty> AddAssign<$component_ty> for $self_ty<$component_ty>
86114
where
87-
T: AddAssign + Clone
115+
T: AddAssign + Clone
88116
{
89117
fn add_assign(&mut self, c: $component_ty) {
90118
$( self.$element += c.clone(); )+
91119
}
92120
}
121+
122+
impl<$component_ty> $crate::num::SaturatingAdd<Self> for $self_ty<$component_ty>
123+
where
124+
T: $crate::num::SaturatingAdd<Output=T>
125+
{
126+
type Output = Self;
127+
128+
fn saturating_add(self, other: Self) -> Self {
129+
$self_ty {
130+
$( $element: self.$element.saturating_add(other.$element), )+
131+
}
132+
}
133+
}
134+
135+
impl<$component_ty> $crate::num::SaturatingAdd<$component_ty> for $self_ty<$component_ty>
136+
where
137+
T: $crate::num::SaturatingAdd<Output=T> + Clone
138+
{
139+
type Output = Self;
140+
141+
fn saturating_add(self, c: $component_ty) -> Self::Output {
142+
$self_ty {
143+
$( $element: self.$element.saturating_add(c.clone()), )+
144+
}
145+
}
146+
}
93147
};
94148
}
95149

@@ -143,6 +197,34 @@ macro_rules! impl_color_sub {
143197
$( self.$element -= c.clone(); )+
144198
}
145199
}
200+
201+
impl<$phantom_ty, $component_ty> $crate::num::SaturatingSub<Self> for $self_ty<$phantom_ty, $component_ty>
202+
where
203+
T: $crate::num::SaturatingSub<Output=$component_ty>
204+
{
205+
type Output = Self;
206+
207+
fn saturating_sub(self, other: Self) -> Self::Output {
208+
$self_ty {
209+
$( $element: self.$element.saturating_sub(other.$element), )+
210+
$phantom: PhantomData,
211+
}
212+
}
213+
}
214+
215+
impl<$phantom_ty, $component_ty> $crate::num::SaturatingSub<$component_ty> for $self_ty<$phantom_ty, $component_ty>
216+
where
217+
T: $crate::num::SaturatingSub<Output=$component_ty> + Clone
218+
{
219+
type Output = Self;
220+
221+
fn saturating_sub(self, c: $component_ty) -> Self::Output {
222+
$self_ty {
223+
$( $element: self.$element.saturating_sub(c.clone()), )+
224+
$phantom: PhantomData,
225+
}
226+
}
227+
}
146228
};
147229

148230
($self_ty: ident < $component_ty: ident > , [$($element: ident),+]) => {
@@ -189,6 +271,32 @@ macro_rules! impl_color_sub {
189271
$( self.$element -= c.clone(); )+
190272
}
191273
}
274+
275+
impl<$component_ty> $crate::num::SaturatingSub<Self> for $self_ty<$component_ty>
276+
where
277+
T: $crate::num::SaturatingSub<Output=T>
278+
{
279+
type Output = Self;
280+
281+
fn saturating_sub(self, other: Self) -> Self {
282+
$self_ty {
283+
$( $element: self.$element.saturating_sub(other.$element), )+
284+
}
285+
}
286+
}
287+
288+
impl<$component_ty> $crate::num::SaturatingSub<$component_ty> for $self_ty<$component_ty>
289+
where
290+
T: $crate::num::SaturatingSub<Output=T> + Clone
291+
{
292+
type Output = Self;
293+
294+
fn saturating_sub(self, c: $component_ty) -> Self::Output {
295+
$self_ty {
296+
$( $element: self.$element.saturating_sub(c.clone()), )+
297+
}
298+
}
299+
}
192300
};
193301
}
194302

palette/src/num.rs

+36
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,26 @@ pub trait MulSub {
286286
fn mul_sub(self, m: Self, s: Self) -> Self;
287287
}
288288

289+
/// Saturating addition operation.
290+
pub trait SaturatingAdd<Rhs = Self> {
291+
/// The resulting type.
292+
type Output;
293+
294+
/// Returns the sum of `self` and `other`, but saturates instead of overflowing.
295+
#[must_use]
296+
fn saturating_add(self, other: Rhs) -> Self::Output;
297+
}
298+
299+
/// Saturating subtraction operation.
300+
pub trait SaturatingSub<Rhs = Self> {
301+
/// The resulting type.
302+
type Output;
303+
304+
/// Returns the difference of `self` and `other`, but saturates instead of overflowing.
305+
#[must_use]
306+
fn saturating_sub(self, other: Rhs) -> Self::Output;
307+
}
308+
289309
macro_rules! impl_uint {
290310
($($ty: ident),+) => {
291311
$(
@@ -409,6 +429,22 @@ macro_rules! impl_uint {
409429
(self * m) - s
410430
}
411431
}
432+
433+
impl SaturatingAdd for $ty {
434+
type Output = $ty;
435+
#[inline]
436+
fn saturating_add(self, other: Self) -> Self{
437+
<$ty>::saturating_add(self, other)
438+
}
439+
}
440+
441+
impl SaturatingSub for $ty {
442+
type Output = $ty;
443+
#[inline]
444+
fn saturating_sub(self, other: Self) -> Self{
445+
<$ty>::saturating_sub(self, other)
446+
}
447+
}
412448
)+
413449
};
414450
}

0 commit comments

Comments
 (0)