Skip to main content

crap4rust/
report.rs

1// Copyright 2025 Umberto Gotti <umberto.gotti@umbertogotti.dev>
2// Licensed under the MIT License or Apache License, Version 2.0
3// SPDX-License-Identifier: MIT OR Apache-2.0
4
5use crate::cli::OutputFormat;
6use crate::model::{Config, ProjectReport, Verdict};
7
8pub fn print_report(report: &ProjectReport, config: &Config) {
9    match config.output_format {
10        OutputFormat::Json => print_json_report(report),
11        OutputFormat::Human => print_human_report(report, config),
12    }
13}
14
15fn print_human_report(report: &ProjectReport, config: &Config) {
16    println!("crap4rust report for {}", report.scope_name);
17    println!();
18
19    let visible_functions = report
20        .functions
21        .iter()
22        .filter(|function| function.verdict != Verdict::Clean)
23        .collect::<Vec<_>>();
24
25    if visible_functions.is_empty() {
26        println!(
27            "No functions at or above the threshold of {:.1}.",
28            config.threshold
29        );
30    } else {
31        let package_width = visible_functions
32            .iter()
33            .map(|function| function.package_name.len())
34            .max()
35            .unwrap_or(7)
36            .max("package".len());
37        let name_width = visible_functions
38            .iter()
39            .map(|function| function.name.len())
40            .max()
41            .unwrap_or(4)
42            .max("name".len());
43        let file_width = visible_functions
44            .iter()
45            .map(|function| function.relative_file.len())
46            .max()
47            .unwrap_or(4)
48            .max("file".len());
49
50        println!(
51            "{:<package_width$}  {:<name_width$}  {:<file_width$}  {:>4}  {:>10}  {:>10}  {:>10}  {:<7}",
52            "package", "name", "file", "line", "complexity", "coverage", "crap", "verdict",
53        );
54        println!(
55            "{}  {}  {}  {}  {}  {}  {}  {}",
56            "-".repeat(package_width),
57            "-".repeat(name_width),
58            "-".repeat(file_width),
59            "-".repeat(4),
60            "-".repeat(10),
61            "-".repeat(10),
62            "-".repeat(10),
63            "-".repeat(7),
64        );
65
66        for function in visible_functions {
67            println!(
68                "{:<package_width$}  {:<name_width$}  {:<file_width$}  {:>4}  {:>10}  {:>9.1}%  {:>10.1}  {:<7}",
69                function.package_name,
70                function.name,
71                function.relative_file,
72                function.line,
73                function.complexity,
74                function.coverage * 100.0,
75                function.crap_score,
76                function.verdict.as_str(),
77            );
78        }
79    }
80
81    println!();
82    println!(
83        "summary: total_functions={} crappy_functions={} crappy_percent={:.1}% threshold={:.1} project_threshold={:.1}% verdict={}",
84        report.total_functions,
85        report.crappy_functions,
86        report.crappy_percent,
87        config.threshold,
88        config.project_threshold,
89        report.verdict.as_str(),
90    );
91}
92
93fn print_json_report(report: &ProjectReport) {
94    let json = serde_json::to_string_pretty(report)
95        .expect("serialization of report to JSON should never fail");
96    println!("{json}");
97}