ktrs_cli/ktlint/reporter/
format.rs1use std::collections::HashMap;
4
5use crate::ktlint::console::Printer;
6use crate::ktlint::reporter::{Color, KtlintCliError, ReporterOptions, ReporterV2, Status, color_file_name, empty_or_true};
7
8pub struct FormatReporter {
10 out: Printer,
11 format: bool,
12 should_color_output: bool,
13 output_color: Color,
14 count_auto_correct_possible_or_done: HashMap<String, usize>,
15 count_can_not_be_auto_corrected: HashMap<String, usize>,
16}
17
18impl FormatReporter {
19 pub fn new(out: Printer, format: bool, should_color_output: bool, output_color: Color) -> FormatReporter {
20 FormatReporter {
21 out,
22 format,
23 should_color_output,
24 output_color,
25 count_auto_correct_possible_or_done: HashMap::new(),
26 count_can_not_be_auto_corrected: HashMap::new(),
27 }
28 }
29
30 fn colored(&self, text: &str) -> String {
31 if self.should_color_output { self.output_color.paint(text) } else { text.to_owned() }
32 }
33}
34
35impl ReporterV2 for FormatReporter {
36 fn on_lint_error(&mut self, file: &str, ktlint_cli_error: &KtlintCliError) {
37 let counts = match ktlint_cli_error.status {
38 Status::LintCanBeAutocorrected | Status::FormatIsAutocorrected => &mut self.count_auto_correct_possible_or_done,
39 _ => &mut self.count_can_not_be_auto_corrected,
40 };
41 *counts.entry(file.to_owned()).or_insert(0) += 1;
42 }
43
44 fn after(&mut self, file: &str) {
45 let can_not_be_autocorrected = self.count_can_not_be_auto_corrected.get(file).copied().unwrap_or(0);
46 let result = match can_not_be_autocorrected {
47 1 if self.format => "Format not completed (1 violation needs manual fixing)".to_owned(),
48 1 => "Format required (1 violation needs manual fixing)".to_owned(),
49 n if n > 1 && self.format => format!("Format not completed ({n} violations need manual fixing)"),
50 n if n > 1 => format!("Format required ({n} violations need manual fixing)"),
51 _ if self.count_auto_correct_possible_or_done.get(file).copied().unwrap_or(0) > 0 => {
52 if self.format {
53 "Format completed (all violations have been fixed)".to_owned()
54 } else {
55 "Format required (all violations can be autocorrected)".to_owned()
56 }
57 }
58 _ => "Format not needed (no violations found)".to_owned(),
59 };
60 let line = format!("{}{} {result}", color_file_name(file, |t| self.colored(t)), self.colored(":"));
61 self.out.println(&line);
62 }
63}
64
65pub struct FormatReporterProvider;
66
67impl FormatReporterProvider {
68 pub const ID: &'static str = "format";
69
70 pub fn get(out: Printer, opt: &ReporterOptions) -> Result<FormatReporter, String> {
71 let format = match opt.get("format") {
72 None => {
73 return Err("java.lang.IllegalArgumentException: Format is not specified in config options".to_owned());
74 }
75 Some("true") => true,
76 Some("false") => false,
77 Some(other) => {
78 return Err(format!(
79 "java.lang.IllegalArgumentException: The string doesn't represent a boolean value: {other}"
80 ));
81 }
82 };
83 let should_color_output = empty_or_true(opt.get("color"));
84 let output_color = Color::from_option(opt.get("color_name"))?;
85 Ok(FormatReporter::new(out, format, should_color_output, output_color))
86 }
87}