pub(crate) mod analyzer;
pub(crate) mod report;
use std::error::Error;
use std::path::Path;
use crate::loc::language::LanguageSpec;
use crate::util::read_and_classify;
use crate::walk::WalkConfig;
use analyzer::analyze;
use report::{FileIndentMetrics, print_json, print_report, print_short, print_terse};
const TAB_WIDTH: usize = 4;
pub(crate) fn analyze_file(
path: &Path,
spec: &LanguageSpec,
) -> Result<Option<FileIndentMetrics>, Box<dyn Error>> {
let (lines, kinds) = match read_and_classify(path, spec)? {
Some(v) => v,
None => return Ok(None),
};
let metrics = match analyze(&lines, &kinds, TAB_WIDTH) {
Some(m) => m,
None => return Ok(None),
};
Ok(Some(FileIndentMetrics {
path: path.to_path_buf(),
code_lines: metrics.code_lines,
stddev: metrics.stddev,
max_depth: metrics.max_depth,
total_indent: metrics.total_indent,
complexity: metrics.complexity,
}))
}
pub fn run(cfg: &WalkConfig<'_>, output: crate::cli::OutputMode) -> Result<(), Box<dyn Error>> {
let mut results = cfg.collect_analysis(analyze_file);
results.sort_by(|a, b| b.stddev.total_cmp(&a.stddev));
match output {
crate::cli::OutputMode::Json => print_json(&results)?,
crate::cli::OutputMode::Short => print_short(&results),
crate::cli::OutputMode::Terse => print_terse(&results),
crate::cli::OutputMode::Github | crate::cli::OutputMode::Codeclimate => {
return Err(crate::cli::ERR_CI_FORMAT_ONLY.into());
}
crate::cli::OutputMode::Table => print_report(&results),
}
Ok(())
}
#[cfg(test)]
#[path = "mod_test.rs"]
mod tests;