retroglyph_widgets/widget/
meter.rs1use retroglyph_core::Color;
3
4#[derive(Clone, Copy, Debug, PartialEq)]
16pub struct Meter {
17 ratio: f32,
18}
19
20impl Meter {
21 const GREEN: Color = Color::Rgb {
22 r: 80,
23 g: 200,
24 b: 120,
25 };
26 const YELLOW: Color = Color::Rgb {
27 r: 220,
28 g: 200,
29 b: 90,
30 };
31 const RED: Color = Color::Rgb {
32 r: 220,
33 g: 90,
34 b: 90,
35 };
36
37 #[must_use]
39 pub const fn new(ratio: f32) -> Self {
40 Self { ratio }
41 }
42
43 #[must_use]
45 pub fn color(self) -> Color {
46 let t = self.ratio.clamp(0.0, 1.0);
47 if t < 0.5 {
48 Color::lerp(Self::GREEN, Self::YELLOW, t * 2.0)
49 } else {
50 Color::lerp(Self::YELLOW, Self::RED, (t - 0.5) * 2.0)
51 }
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn low_load_is_green() {
61 assert_eq!(Meter::new(0.0).color(), Meter::GREEN);
62 }
63
64 #[test]
65 fn mid_load_is_yellow() {
66 assert_eq!(Meter::new(0.5).color(), Meter::YELLOW);
67 }
68
69 #[test]
70 fn high_load_is_red() {
71 assert_eq!(Meter::new(1.0).color(), Meter::RED);
72 }
73
74 #[test]
75 fn out_of_range_ratios_are_clamped() {
76 assert_eq!(Meter::new(-1.0).color(), Meter::GREEN);
77 assert_eq!(Meter::new(2.0).color(), Meter::RED);
78 }
79}