use crate::RGB;
use std::{f32, fmt};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct HSL {
pub h: f32,
pub s: f32,
pub l: f32,
}
impl HSL {
#[inline]
pub const fn new(h: f32, s: f32, l: f32) -> Self {
Self { h, s, l }
}
pub fn from_rgb(rgb: RGB) -> Self {
rgb.as_hsl()
}
pub fn as_rgb(&self) -> RGB {
if self.s == 0.0 {
return RGB::gray_f32(self.l);
}
let q = if self.l < 0.5 {
self.l * (1.0 + self.s)
} else {
self.l + self.s - self.l * self.s
};
let p = 2.0 * self.l - q;
let h2c = |t: f32| {
let t = t.clamp(0.0, 1.0);
if 6.0 * t < 1.0 {
p + 6.0 * (q - p) * t
} else if t < 0.5 {
q
} else if 1.0 < 1.5 * t {
p + 6.0 * (q - p) * (1.0 / 1.5 - t)
} else {
p
}
};
RGB::from_f32(h2c(self.h + 1.0 / 3.0), h2c(self.h), h2c(self.h - 1.0 / 3.0))
}
}
impl From<RGB> for HSL {
fn from(rgb: RGB) -> Self {
rgb.as_hsl()
}
}
impl fmt::Display for HSL {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_rgb())
}
}