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
use super::Hsl;

// use crate::common::simple_rand;

#[allow(unused_imports)]
use crate::{common, normalize::normalize_opt_ratio, ColorAlpha, ColorTuple, ColorTupleA, Rgb};
use common::{approx::*, ops};

use std::ops::{Add, AddAssign, Sub, SubAssign};

fn add_sub(hsl1: &Hsl, hsl2: &Hsl, is_add: bool) -> Hsl {
  type TA = (ColorTuple, Option<f64>);
  let ta1: TA = (hsl1.into(), hsl1.a);
  let ta2: TA = (hsl2.into(), hsl2.a);
  let (t, a) = ops::add_sub_tuples_a(&ta1, &ta2, is_add);
  let mut hsl = Hsl::from(t);
  hsl.a = normalize_opt_ratio(a);
  hsl
}

fn add(hsl1: &Hsl, hsl2: &Hsl) -> Hsl {
  add_sub(hsl1, hsl2, true)
}

fn sub(hsl1: &Hsl, hsl2: &Hsl) -> Hsl {
  add_sub(hsl1, hsl2, false)
}

impl<'a> Add for &'a Hsl {
  type Output = Hsl;
  fn add(self, rhs: &Hsl) -> Hsl {
    add(self, rhs)
  }
}

impl<'a> Add for &'a mut Hsl {
  type Output = Hsl;
  fn add(self, rhs: &'a mut Hsl) -> Hsl {
    add(self, rhs)
  }
}

impl Add for Hsl {
  type Output = Hsl;
  fn add(self, rhs: Self) -> Self {
    add(&self, &rhs)
  }
}

impl AddAssign for Hsl {
  fn add_assign(&mut self, rhs: Self) {
    *self = add(self, &rhs);
  }
}

impl Sub for Hsl {
  type Output = Hsl;
  fn sub(self, rhs: Self) -> Self {
    sub(&self, &rhs)
  }
}

impl<'a> Sub for &'a Hsl {
  type Output = Hsl;
  fn sub(self, rhs: Self) -> Hsl {
    sub(self, rhs)
  }
}

impl<'a> Sub for &'a mut Hsl {
  type Output = Hsl;
  fn sub(self, rhs: Self) -> Hsl {
    sub(self, rhs)
  }
}

impl SubAssign for Hsl {
  fn sub_assign(&mut self, rhs: Self) {
    *self = sub(self, &rhs);
  }
}

impl ApproxEq<Hsl> for Hsl {
  fn approx_eq(&self, other: &Hsl) -> bool {
    let t1: ColorTuple = self.into();
    let t2: ColorTuple = other.into();
    approx_tuple_def(&t1, &t2) && approx_def(self.get_alpha(), other.get_alpha())
  }
  fn approx_eq_clarify(&self, other: &Hsl, precision: f64) -> bool {
    let t1: ColorTuple = self.into();
    let t2: ColorTuple = other.into();
    approx_tuple(&t1, &t2, precision) && approx(self.get_alpha(), other.get_alpha(), precision)
  }
}

impl ApproxEq<Rgb> for Hsl {
  fn approx_eq(&self, rgb: &Rgb) -> bool {
    self.approx_eq_clarify(rgb, DEFAULT_APPROX_EQ_PRECISION)
  }
  fn approx_eq_clarify(&self, rgb: &Rgb, precision: f64) -> bool {
    let t1: ColorTuple = self.into();
    let t2: ColorTuple = Hsl::from(rgb).into();
    approx_tuple(&t1, &t2, precision) && approx(self.get_alpha(), rgb.get_alpha(), precision)
  }
}

#[test]
fn hsl_add() {}

#[test]
fn hsl_eq() {}