ktrs_cli/ktlint/reporter/
html.rs1use crate::ktlint::console::{LINE_SEPARATOR, Printer};
4use crate::ktlint::reporter::java_map::JavaConcurrentHashMap;
5use crate::ktlint::reporter::{KtlintCliError, ReporterV2, Status, escape_xml_attr_value};
6
7pub struct HtmlReporter {
8 out: Printer,
9 acc: JavaConcurrentHashMap<Vec<KtlintCliError>>,
10 issue_count: usize,
11 corrected_count: usize,
12}
13
14impl HtmlReporter {
15 pub fn new(out: Printer) -> HtmlReporter {
16 HtmlReporter { out, acc: JavaConcurrentHashMap::new(), issue_count: 0, corrected_count: 0 }
17 }
18
19 fn head(&mut self) {
20 let out = &mut self.out;
21 out.println("<head>");
22 out.print("<link href=\"");
23 out.print("https://fonts.googleapis.com/css?family=Source+Code+Pro");
24 out.println("\" rel=\"stylesheet\" />");
25 out.print(&format!("<meta http-equiv=\"Content-Type\" Content=\"text/html; Charset=UTF-8\">{LINE_SEPARATOR}"));
26 out.print(&format!("<style>{LINE_SEPARATOR}"));
27 out.print(&format!("body {{{LINE_SEPARATOR}"));
28 out.print(&format!(" font-family: 'Source Code Pro', monospace;{LINE_SEPARATOR}"));
29 out.print(&format!("}}{LINE_SEPARATOR}"));
30 out.print(&format!("h3 {{{LINE_SEPARATOR}"));
31 out.print(&format!(" font-size: 12pt;{LINE_SEPARATOR}"));
32 out.print("}");
33 out.print(&format!("</style>{LINE_SEPARATOR}"));
34 out.println("</head>");
35 }
36
37 fn body(&mut self) {
38 let out = &mut self.out;
39 out.println("<body>");
40 if !self.acc.is_empty() {
41 out.print("<h1>");
42 out.print("Overview");
43 out.println("</h1>");
44 paragraph(out, &format!("Issues found: {}", self.issue_count));
45 paragraph(out, &format!("Issues corrected: {}", self.corrected_count));
46 for (file, errors) in self.acc.iter() {
47 out.print("<h3>");
48 out.print(file);
49 out.println("</h3>");
50 out.println("<ul>");
51 for err in errors {
52 out.print("<li>");
53 out.print(&escape_xml_attr_value(&format!(
54 "({}, {}): {} ({})",
55 err.line, err.col, err.detail, err.rule_id
56 )));
57 out.println("</li>");
58 }
59 out.println("</ul>");
60 }
61 } else {
62 paragraph(out, "Congratulations, no issues found!");
63 }
64 out.println("</body>");
65 }
66}
67
68fn paragraph(out: &mut Printer, text: &str) {
69 out.print("<p>");
70 out.print(text);
71 out.println("</p>");
72}
73
74impl ReporterV2 for HtmlReporter {
75 fn on_lint_error(&mut self, file: &str, ktlint_cli_error: &KtlintCliError) {
76 if ktlint_cli_error.status != Status::FormatIsAutocorrected {
77 self.issue_count += 1;
78 self.acc.get_or_put(file, Vec::new).push(ktlint_cli_error.clone());
79 } else {
80 self.corrected_count += 1;
81 }
82 }
83
84 fn after_all(&mut self) {
85 self.out.println("<html>");
86 self.head();
87 self.body();
88 self.out.println("</html>");
89 }
90}