use yansi::Color;
pub struct ColorGenerator {
state: [u16; 3],
min_brightness: f32,
}
impl Default for ColorGenerator {
fn default() -> Self {
Self::from_state([5000, 5000, 20000], 0.5)
}
}
impl ColorGenerator {
#[must_use]
pub fn from_state(state: [u16; 3], min_brightness: f32) -> Self {
Self {
state,
min_brightness: min_brightness.clamp(0.0, 1.0),
}
}
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Color {
#[allow(clippy::cast_possible_truncation)]
for i in 0..3 {
self.state[i] = (self.state[i] as usize).wrapping_add(40503 * (i * 4 + 1130)) as u16;
}
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_sign_loss)]
Color::Fixed(
16 + (f32::from(self.state[0]) / 65535.0)
.mul_add(1.0 - self.min_brightness, self.min_brightness)
.mul_add(
180.0,
(f32::from(self.state[2]) / 65535.0)
.mul_add(1.0 - self.min_brightness, self.min_brightness)
.mul_add(
5.0,
(f32::from(self.state[1]) / 65535.0)
.mul_add(1.0 - self.min_brightness, self.min_brightness)
* 30.0,
),
) as u8,
)
}
}
impl Iterator for ColorGenerator {
type Item = Color;
fn next(&mut self) -> Option<Self::Item> {
Some(self.next())
}
}