pub const SCORE_CRITICAL: f64 = 25.0;
pub const SCORE_HIGH: f64 = 15.0;
pub const SCORE_MEDIUM: f64 = 8.0;
pub const CC_SPLIT_HIGH: usize = 15;
pub const CC_SPLIT_MEDIUM: usize = 10;
pub const NESTING_HIGH: usize = 3;
pub const PATH_COUNT_NOTABLE: usize = 50;
pub const BLOCK_COUNT_NOTABLE: usize = 40;
pub fn classify_score(score: f64) -> &'static str {
if score >= SCORE_CRITICAL {
"critical"
} else if score >= SCORE_HIGH {
"high"
} else if score >= SCORE_MEDIUM {
"medium"
} else {
"low"
}
}
pub fn composite_score(
complexity: usize,
path_count: usize,
error_ratio: f64,
block_count: usize,
nesting: usize,
) -> f64 {
let complexity_weight = (complexity as f64).ln_1p() * 3.0;
let path_weight = (path_count as f64).ln_1p() * 2.0;
let error_weight = error_ratio * 5.0;
let size_weight = (block_count as f64).ln_1p() * 1.0;
let nesting_weight = (nesting as f64) * 4.0;
complexity_weight + path_weight + error_weight + size_weight + nesting_weight
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_classify_score_bands() {
assert_eq!(classify_score(0.0), "low");
assert_eq!(classify_score(7.9), "low");
assert_eq!(classify_score(8.0), "medium");
assert_eq!(classify_score(14.9), "medium");
assert_eq!(classify_score(15.0), "high");
assert_eq!(classify_score(24.9), "high");
assert_eq!(classify_score(25.0), "critical");
assert_eq!(classify_score(100.0), "critical");
}
#[test]
fn test_composite_score_monotonic() {
let s1 = composite_score(5, 10, 0.1, 20, 1);
let s2 = composite_score(20, 50, 0.5, 100, 3);
assert!(s2 > s1, "higher inputs should produce higher score");
}
}