mod spans;
pub(super) use spans::{
extract_function_name, function_spans_for_cognitive_language, function_spans_for_language,
};
#[cfg(test)]
#[derive(Debug, Clone, PartialEq)]
pub struct FunctionMetrics {
pub function_count: usize,
pub max_function_length: usize,
pub avg_function_length: f64,
pub functions_over_threshold: usize,
}
#[cfg(test)]
impl Default for FunctionMetrics {
fn default() -> Self {
Self {
function_count: 0,
max_function_length: 0,
avg_function_length: 0.0,
functions_over_threshold: 0,
}
}
}
#[cfg(test)]
const LONG_FUNCTION_THRESHOLD: usize = 100;
#[cfg(test)]
pub fn analyze_functions(content: &str, language: &str) -> FunctionMetrics {
let lang = language.to_lowercase();
let lines: Vec<&str> = content.lines().collect();
if lines.is_empty() {
return FunctionMetrics::default();
}
let spans = function_spans_for_language(&lines, &lang);
compute_metrics(&spans)
}
#[cfg(test)]
fn compute_metrics(spans: &[spans::FunctionSpan]) -> FunctionMetrics {
if spans.is_empty() {
return FunctionMetrics::default();
}
let lengths: Vec<usize> = spans.iter().map(spans::FunctionSpan::length).collect();
let function_count = lengths.len();
let max_function_length = lengths.iter().copied().max().unwrap_or(0);
let total_length: usize = lengths.iter().sum();
let avg_function_length = total_length as f64 / function_count as f64;
let functions_over_threshold = lengths
.iter()
.filter(|&&len| len > LONG_FUNCTION_THRESHOLD)
.count();
FunctionMetrics {
function_count,
max_function_length,
avg_function_length,
functions_over_threshold,
}
}