codelens_core/insight/
mod.rs1pub mod health;
4pub mod hotspot;
5pub mod scoring;
6pub mod trend;
7
8use serde::Serialize;
9use std::fmt;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
13pub enum Grade {
14 A,
15 B,
16 C,
17 D,
18 F,
19}
20
21impl fmt::Display for Grade {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 match self {
24 Grade::A => write!(f, "A"),
25 Grade::B => write!(f, "B"),
26 Grade::C => write!(f, "C"),
27 Grade::D => write!(f, "D"),
28 Grade::F => write!(f, "F"),
29 }
30 }
31}
32
33#[derive(Debug, Clone, Serialize)]
35pub struct DeltaValue<T: Serialize> {
36 pub from: T,
37 pub to: T,
38 pub delta: T,
39 pub percent: f64,
40}
41
42impl DeltaValue<usize> {
43 pub fn new(from: usize, to: usize) -> Self {
44 let delta = to.saturating_sub(from);
45 let percent = if from > 0 {
46 (to as f64 - from as f64) / from as f64 * 100.0
47 } else if to > 0 {
48 100.0
49 } else {
50 0.0
51 };
52 Self {
53 from,
54 to,
55 delta,
56 percent,
57 }
58 }
59
60 pub fn signed_delta(&self) -> i64 {
61 self.to as i64 - self.from as i64
62 }
63}
64
65impl DeltaValue<f64> {
66 pub fn new_f64(from: f64, to: f64) -> Self {
67 let delta = to - from;
68 let percent = if from.abs() > f64::EPSILON {
69 delta / from * 100.0
70 } else if to.abs() > f64::EPSILON {
71 100.0
72 } else {
73 0.0
74 };
75 Self {
76 from,
77 to,
78 delta,
79 percent,
80 }
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_grade_display() {
90 assert_eq!(Grade::A.to_string(), "A");
91 assert_eq!(Grade::F.to_string(), "F");
92 }
93
94 #[test]
95 fn test_grade_ordering() {
96 assert!(Grade::A < Grade::B);
97 assert!(Grade::B < Grade::F);
98 }
99
100 #[test]
101 fn test_delta_value_increase() {
102 let d = DeltaValue::new(100, 120);
103 assert_eq!(d.delta, 20);
104 assert!((d.percent - 20.0).abs() < 0.01);
105 assert_eq!(d.signed_delta(), 20);
106 }
107
108 #[test]
109 fn test_delta_value_decrease() {
110 let d = DeltaValue::new(100, 80);
111 assert_eq!(d.delta, 0);
112 assert_eq!(d.signed_delta(), -20);
113 assert!((d.percent - (-20.0)).abs() < 0.01);
114 }
115
116 #[test]
117 fn test_delta_value_from_zero() {
118 let d = DeltaValue::new(0, 50);
119 assert!((d.percent - 100.0).abs() < 0.01);
120 }
121
122 #[test]
123 fn test_delta_value_f64() {
124 let d = DeltaValue::new_f64(82.0, 78.0);
125 assert!((d.delta - (-4.0)).abs() < 0.01);
126 }
127}