tuigui 0.23.0

An easy-to-use, highly extensible, and speedy TUI library.
Documentation
macro_rules! include {
    ($module: ident) => {
        mod $module;
        pub use $module::*;
    };
}

include!(animation_dyn);
include!(quadratic_bezier);
include!(cubic_bezier);

macro_rules! custom_lerp_preset {
    ($preset: ident, $lerp: ident) => {
        pub fn $preset(end: crate::Transform, last_for_seconds: f64) -> CustomLerp {
            return CustomLerp::new(
                functions::$lerp,
                end,
                last_for_seconds,
            );
        }
    };
}

custom_lerp_preset!(linear, lerp);
custom_lerp_preset!(smooth, lerp_smooth);

pub mod functions {
    pub fn lerp(a: f64, b: f64, t: f64) -> f64 {
        return a + (b - a) * t;
    }

    pub fn lerp_smooth(a: f64, b: f64, t: f64) -> f64 {
        return lerp(a, b, t * t * (3.0 - 2.0 * t));
    }

    pub fn quadratic_bezier(a: f64, control: f64, b: f64, t: f64) -> f64 {
        let l1 = lerp(a, control, t);
        let l2 = lerp(control, b, t);

        return lerp(l1, l2, t);
    }

    pub fn cubic_bezier(a: f64, a_control: f64, b: f64, b_control: f64, t: f64) -> f64 {
        let l1 = lerp(a, a_control, t);
        let l2 = lerp(a_control, b_control, t);
        let l3 = lerp(b_control, b, t);

        let q1 = lerp(l1, l2, t);
        let q2 = lerp(l2, l3, t);

        return lerp(q1, q2, t);
    }
}

#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
/// Simple animation type that takes in a custom lerp function
/// where the 1st param is A, the 2nd param is B, and the 3rd param is T
pub struct CustomLerp {
    pub lerp: fn(f64, f64, f64) -> f64,
    pub end: crate::Transform,
    pub last_for_seconds: f64,
}

impl CustomLerp {
    pub fn new(
        lerp: fn(f64, f64, f64) -> f64,
        end: crate::Transform,
        last_for_seconds: f64,
    ) -> Self {
        Self {
            lerp,
            end,
            last_for_seconds,
        }
    }
}

impl crate::Animation for CustomLerp {
    fn animated_transform(&mut self, original_transform: crate::Transform, duration_seconds: f64) -> crate::Transform {
        let t: f64;

        if self.last_for_seconds == 0.0 {
            t = 0.0;
        } else {
            if duration_seconds <= self.last_for_seconds {
                t = (self.last_for_seconds - duration_seconds) / self.last_for_seconds;
            } else {
                t = 0.0;
            }
        }

        return self.end.apply_lerp(original_transform, t, self.lerp);
    }

    fn is_done(&self, duration_seconds: f64) -> bool {
        return duration_seconds >= self.last_for_seconds;
    }
}