colorsys 0.7.3

A module for color conversion and mutation. Works with RGB(a)( as hexadecimal too), HSL(a), CMYK color models and with ANSI color codes
Documentation
use super::unit::Unit;

use crate::common::approx::approx;
use crate::consts::RATIO_MAX;
use crate::{ApproxEq, DEFAULT_APPROX_EQ_PRECISION};

#[derive(Clone, PartialEq, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) struct Alpha {
  value: Option<Unit>,
}

impl Alpha {
  pub(crate) fn set(&mut self, a: f64) {
    if let Some(u) = &mut self.value {
      u.set(a);
    } else {
      self.value = Some(Unit::new_ratio(a));
    }
    if self.value.unwrap().value.eq(&RATIO_MAX) {
      self.value = None;
    }
  }
  pub(crate) fn set_opt(&mut self, av: Option<f64>) {
    if let Some(a) = av {
      self.set(a);
    } else {
      self.value = None;
    }
  }

  pub(crate) fn get(&self) -> Option<f64> {
    self.value.map(|u| u.value)
  }
  pub(crate) fn get_f64(&self) -> f64 {
    self.get().unwrap_or(RATIO_MAX)
  }

  pub(crate) fn opacify(&mut self, v: f64) {
    self.set(self.get_f64() + v);
  }
}

impl ApproxEq<Alpha> for Alpha {
  fn approx_eq(&self, other: &Alpha) -> bool {
    self.approx_eq_clarify(other, DEFAULT_APPROX_EQ_PRECISION)
  }

  fn approx_eq_clarify(&self, other: &Alpha, precision: f64) -> bool {
    if let Some(su) = &self.value {
      if let Some(ou) = &other.value {
        return approx(su.value, ou.value, precision);
      }
    } else {
      return other.value.is_none();
    }
    false
  }
}