fn clamp(value: f32, min: f32, max: f32) -> f32 {
if value < min {
min
} else if value > max {
max
} else {
value
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct RgbColor {
r: f32,
g: f32,
b: f32,
}
impl RgbColor {
pub fn new(r: f32, g: f32, b: f32) -> Self {
Self {
r: clamp(r, 0.0, 1.0),
g: clamp(g, 0.0, 1.0),
b: clamp(b, 0.0, 1.0),
}
}
pub fn red(&self) -> f32 { self.r }
pub fn green(&self) -> f32 { self.g }
pub fn blue(&self) -> f32 { self.b }
pub fn to_array(&self) -> [f32; 3] { [self.r, self.g, self.b] }
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CmykColor {
c: f32,
m: f32,
y: f32,
k: f32,
}
impl CmykColor {
pub fn new(c: f32, m: f32, y: f32, k: f32) -> Self {
Self {
c: clamp(c, 0.0, 1.0),
m: clamp(m, 0.0, 1.0),
y: clamp(y, 0.0, 1.0),
k: clamp(k, 0.0, 1.0),
}
}
pub fn cyan(&self) -> f32 { self.c }
pub fn magenta(&self) -> f32 { self.m }
pub fn yellow(&self) -> f32 { self.y }
pub fn key(&self) -> f32 { self.k }
pub fn to_array(&self) -> [f32; 4] { [self.c, self.m, self.y, self.k] }
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct LabColor {
l: f32,
a: f32,
b: f32,
}
impl LabColor {
pub fn new(l: f32, a: f32, b: f32) -> Self {
Self {
l: clamp(l, 0.0, 100.0),
a: clamp(a, -128.0, 127.0),
b: clamp(b, -128.0, 127.0),
}
}
pub fn l(&self) -> f32 { self.l }
pub fn a(&self) -> f32 { self.a }
pub fn b(&self) -> f32 { self.b }
pub fn to_array(&self) -> [f32; 3] { [self.l, self.a, self.b] }
}