#![cfg_attr(coverage_nightly, coverage(off))]
use super::analysis::{
analyze_file_metrics, build_complexity_report, calculate_summary_statistics,
calculate_technical_debt,
};
use super::rules::{CognitiveComplexityRule, CyclomaticComplexityRule};
use super::types::{ComplexityReport, ComplexityThresholds, FileComplexityMetrics};
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn aggregate_results(file_metrics: Vec<FileComplexityMetrics>) -> ComplexityReport {
aggregate_results_with_thresholds(file_metrics, None, None)
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn aggregate_results_with_thresholds(
file_metrics: Vec<FileComplexityMetrics>,
max_cyclomatic: Option<u16>,
max_cognitive: Option<u16>,
) -> ComplexityReport {
let thresholds = build_custom_thresholds(max_cyclomatic, max_cognitive);
let rules = create_complexity_rules(&thresholds);
let mut analysis_data = analyze_file_metrics(&file_metrics, &rules, &thresholds);
let summary_stats = calculate_summary_statistics(&mut analysis_data);
let technical_debt = calculate_technical_debt(&analysis_data.violations);
build_complexity_report(file_metrics, analysis_data, summary_stats, technical_debt)
}
fn build_custom_thresholds(
max_cyclomatic: Option<u16>,
max_cognitive: Option<u16>,
) -> ComplexityThresholds {
let mut thresholds = ComplexityThresholds::default();
if let Some(max_cyc) = max_cyclomatic {
thresholds.cyclomatic_warn = max_cyc.saturating_sub(2).max(1);
thresholds.cyclomatic_error = max_cyc;
}
if let Some(max_cog) = max_cognitive {
thresholds.cognitive_warn = max_cog.saturating_sub(2).max(1);
thresholds.cognitive_error = max_cog;
}
thresholds
}
fn create_complexity_rules(
thresholds: &ComplexityThresholds,
) -> (CyclomaticComplexityRule, CognitiveComplexityRule) {
let cyclomatic_rule = CyclomaticComplexityRule::new(thresholds);
let cognitive_rule = CognitiveComplexityRule::new(thresholds);
(cyclomatic_rule, cognitive_rule)
}