lifehash 0.1.0

A Lifehash implementation in Rust
Documentation
use crate::colors::gradient::make_hue;
use crate::colors::{rgb::Color, BLACK};
use crate::utils::modulo;

pub enum ColorFunction<'a> {
    Blend(Color, Color),
    BlendRef(&'a [Color]),
    BlendVec(Vec<Color>),
    Reverse(Box<ColorFunction<'a>>),
    MakeHue,
}
impl ColorFunction<'_> {
    pub fn apply(&self, t: f64) -> Color {
        match self {
            ColorFunction::Blend(color1, color2) => color1.lerp_to(color2, t),
            ColorFunction::BlendVec(colors) => blend_vals(t, colors.as_slice()),
            ColorFunction::BlendRef(colors) => blend_vals(t, colors),
            ColorFunction::Reverse(func) => func.apply(1.0 - t),
            ColorFunction::MakeHue => make_hue(t).unwrap(),
        }
    }
}
fn blend_vals(t: f64, colors: &[Color]) -> Color {
    if colors.is_empty() {
        ColorFunction::Blend(BLACK, BLACK).apply(t)
    } else if colors.len() == 1 {
        ColorFunction::Blend(colors[0], colors[0]).apply(t)
    } else if colors.len() == 2 {
        ColorFunction::Blend(colors[0], colors[1]).apply(t)
    } else if t >= 1.0 {
        colors[colors.len() - 1]
    } else if t <= 0.0 {
        colors[0]
    } else {
        let segments = colors.len() - 1;
        let s = t * segments as f64;
        let segment = s as usize;
        let segment_frac = modulo(s, 1.0);
        let c1 = colors[segment];
        let c2 = colors[segment + 1];
        c1.lerp_to(&c2, segment_frac)
    }
}