1
+ //! JSON output and comparison functionality for Clippy warnings.
2
+ //!
3
+ //! This module handles serialization of Clippy warnings to JSON format,
4
+ //! loading warnings from JSON files, and generating human-readable diffs
5
+ //! between different linting runs.
6
+
1
7
use std:: fs;
2
8
use std:: path:: Path ;
3
9
@@ -8,8 +14,10 @@ use crate::ClippyWarning;
8
14
9
15
/// This is the total number. 300 warnings results in 100 messages per section.
10
16
const DEFAULT_LIMIT_PER_LINT : usize = 300 ;
17
+ /// Target for total warnings to display across all lints when truncating output.
11
18
const TRUNCATION_TOTAL_TARGET : usize = 1000 ;
12
19
20
+ /// Representation of a single Clippy warning for JSON serialization.
13
21
#[ derive( Debug , Deserialize , Serialize ) ]
14
22
struct LintJson {
15
23
/// The lint name e.g. `clippy::bytes_nth`
@@ -21,10 +29,12 @@ struct LintJson {
21
29
}
22
30
23
31
impl LintJson {
32
+ /// Returns a tuple of name and `file_line` for sorting and comparison.
24
33
fn key ( & self ) -> impl Ord + ' _ {
25
34
( self . name . as_str ( ) , self . file_line . as_str ( ) )
26
35
}
27
36
37
+ /// Formats the warning information with an action verb for display.
28
38
fn info_text ( & self , action : & str ) -> String {
29
39
format ! ( "{action} `{}` at [`{}`]({})" , self . name, self . file_line, self . file_url)
30
40
}
@@ -53,12 +63,17 @@ pub(crate) fn output(clippy_warnings: Vec<ClippyWarning>) -> String {
53
63
serde_json:: to_string ( & lints) . unwrap ( )
54
64
}
55
65
66
+ /// Loads lint warnings from a JSON file at the given path.
56
67
fn load_warnings ( path : & Path ) -> Vec < LintJson > {
57
68
let file = fs:: read ( path) . unwrap_or_else ( |e| panic ! ( "failed to read {}: {e}" , path. display( ) ) ) ;
58
69
59
70
serde_json:: from_slice ( & file) . unwrap_or_else ( |e| panic ! ( "failed to deserialize {}: {e}" , path. display( ) ) )
60
71
}
61
72
73
+ /// Generates and prints a diff between two sets of lint warnings.
74
+ ///
75
+ /// Compares warnings from `old_path` and `new_path`, then displays a summary table
76
+ /// and detailed information about added, removed, and changed warnings.
62
77
pub ( crate ) fn diff ( old_path : & Path , new_path : & Path , truncate : bool ) {
63
78
let old_warnings = load_warnings ( old_path) ;
64
79
let new_warnings = load_warnings ( new_path) ;
@@ -116,6 +131,7 @@ pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
116
131
}
117
132
}
118
133
134
+ /// Container for grouped lint warnings organized by status (added/removed/changed).
119
135
#[ derive( Debug ) ]
120
136
struct LintWarnings {
121
137
name : String ,
@@ -124,6 +140,7 @@ struct LintWarnings {
124
140
changed : Vec < ( LintJson , LintJson ) > ,
125
141
}
126
142
143
+ /// Prints a formatted report for a single lint type with its warnings.
127
144
fn print_lint_warnings ( lint : & LintWarnings , truncate_after : usize ) {
128
145
let name = & lint. name ;
129
146
let html_id = to_html_id ( name) ;
@@ -145,6 +162,7 @@ fn print_lint_warnings(lint: &LintWarnings, truncate_after: usize) {
145
162
print_changed_diff ( & lint. changed , truncate_after / 3 ) ;
146
163
}
147
164
165
+ /// Prints a summary table of all lints with counts of added, removed, and changed warnings.
148
166
fn print_summary_table ( lints : & [ LintWarnings ] ) {
149
167
println ! ( "| Lint | Added | Removed | Changed |" ) ;
150
168
println ! ( "| ------------------------------------------ | ------: | ------: | ------: |" ) ;
@@ -160,6 +178,7 @@ fn print_summary_table(lints: &[LintWarnings]) {
160
178
}
161
179
}
162
180
181
+ /// Prints a section of warnings with a header and formatted code blocks.
163
182
fn print_warnings ( title : & str , warnings : & [ LintJson ] , truncate_after : usize ) {
164
183
if warnings. is_empty ( ) {
165
184
return ;
@@ -180,6 +199,7 @@ fn print_warnings(title: &str, warnings: &[LintJson], truncate_after: usize) {
180
199
}
181
200
}
182
201
202
+ /// Prints a section of changed warnings with unified diff format.
183
203
fn print_changed_diff ( changed : & [ ( LintJson , LintJson ) ] , truncate_after : usize ) {
184
204
if changed. is_empty ( ) {
185
205
return ;
@@ -213,6 +233,7 @@ fn print_changed_diff(changed: &[(LintJson, LintJson)], truncate_after: usize) {
213
233
}
214
234
}
215
235
236
+ /// Truncates a list to a maximum number of items and prints a message about truncation.
216
237
fn truncate < T > ( list : & [ T ] , truncate_after : usize ) -> & [ T ] {
217
238
if list. len ( ) > truncate_after {
218
239
println ! (
@@ -227,6 +248,7 @@ fn truncate<T>(list: &[T], truncate_after: usize) -> &[T] {
227
248
}
228
249
}
229
250
251
+ /// Prints a level 3 heading with an appropriate HTML ID for linking.
230
252
fn print_h3 ( lint : & str , title : & str ) {
231
253
let html_id = to_html_id ( lint) ;
232
254
// We have to use HTML here to be able to manually add an id.
0 commit comments