1- use std:: collections:: BTreeSet ;
21use std:: fs;
32use std:: path:: Path ;
43
@@ -23,7 +22,7 @@ struct LintJson {
2322
2423impl LintJson {
2524 fn key ( & self ) -> impl Ord + ' _ {
26- ( self . file_name . as_str ( ) , self . byte_pos , self . lint . as_str ( ) )
25+ ( self . lint . as_str ( ) , self . file_name . as_str ( ) , self . byte_pos )
2726 }
2827
2928 fn info_text ( & self , action : & str ) -> String {
@@ -61,24 +60,33 @@ pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
6160 let old_warnings = load_warnings ( old_path) ;
6261 let new_warnings = load_warnings ( new_path) ;
6362
64- let mut added = Vec :: new ( ) ;
65- let mut removed = Vec :: new ( ) ;
66- let mut changed = Vec :: new ( ) ;
67-
63+ let mut lint_warnings: Vec < LintWarnings > = vec ! [ ] ;
6864 for change in itertools:: merge_join_by ( old_warnings, new_warnings, |old, new| old. key ( ) . cmp ( & new. key ( ) ) ) {
65+ if let Some ( ( old, new) ) = change. as_ref ( ) . both ( )
66+ && old. rendered == new. rendered
67+ {
68+ continue ;
69+ }
70+
71+ let name = & change. as_ref ( ) . into_left ( ) . lint ;
72+ let warnings = if let Some ( warnings) = lint_warnings. last_mut ( )
73+ && & warnings. name == name
74+ {
75+ warnings
76+ } else {
77+ lint_warnings. push ( LintWarnings :: new ( name. to_string ( ) ) ) ;
78+ lint_warnings. last_mut ( ) . unwrap ( )
79+ } ;
80+
6981 match change {
7082 EitherOrBoth :: Both ( old, new) => {
71- if old. rendered != new. rendered {
72- changed. push ( ( old, new) ) ;
73- }
83+ warnings. changed . push ( ( old, new) ) ;
7484 } ,
75- EitherOrBoth :: Left ( old) => removed. push ( old) ,
76- EitherOrBoth :: Right ( new) => added. push ( new) ,
85+ EitherOrBoth :: Left ( old) => warnings . removed . push ( old) ,
86+ EitherOrBoth :: Right ( new) => warnings . added . push ( new) ,
7787 }
7888 }
7989
80- let lint_warnings = group_by_lint ( added, removed, changed) ;
81-
8290 print_summary_table ( & lint_warnings) ;
8391 println ! ( ) ;
8492
@@ -110,60 +118,24 @@ struct LintWarnings {
110118 changed : Vec < ( LintJson , LintJson ) > ,
111119}
112120
113- fn group_by_lint (
114- mut added : Vec < LintJson > ,
115- mut removed : Vec < LintJson > ,
116- mut changed : Vec < ( LintJson , LintJson ) > ,
117- ) -> Vec < LintWarnings > {
118- /// Collects items from an iterator while the condition is met
119- fn collect_while < T , F > ( iter : & mut std:: iter:: Peekable < impl Iterator < Item = T > > , mut condition : F ) -> Vec < T >
120- where
121- F : FnMut ( & T ) -> bool ,
122- {
123- let mut items = vec ! [ ] ;
124- while iter. peek ( ) . map_or ( false , & mut condition) {
125- items. push ( iter. next ( ) . unwrap ( ) ) ;
126- }
127- items
128- }
129-
130- // Sort
131- added. sort_unstable_by ( |a, b| a. lint . cmp ( & b. lint ) ) ;
132- removed. sort_unstable_by ( |a, b| a. lint . cmp ( & b. lint ) ) ;
133- changed. sort_unstable_by ( |( a, _) , ( b, _) | a. lint . cmp ( & b. lint ) ) ;
134-
135- // Collect lint names
136- let lint_names: BTreeSet < _ > = added
137- . iter ( )
138- . chain ( removed. iter ( ) )
139- . chain ( changed. iter ( ) . map ( |( a, _) | a) )
140- . map ( |warning| & warning. lint )
141- . cloned ( )
142- . collect ( ) ;
143-
144- let mut added_iter = added. into_iter ( ) . peekable ( ) ;
145- let mut removed_iter = removed. into_iter ( ) . peekable ( ) ;
146- let mut changed_iter = changed. into_iter ( ) . peekable ( ) ;
147-
148- let mut lints = vec ! [ ] ;
149- for name in lint_names {
150- lints. push ( LintWarnings {
151- added : collect_while ( & mut added_iter, |warning| warning. lint == name) ,
152- removed : collect_while ( & mut removed_iter, |warning| warning. lint == name) ,
153- changed : collect_while ( & mut changed_iter, |( warning, _) | warning. lint == name) ,
121+ impl LintWarnings {
122+ #[ must_use]
123+ fn new ( name : String ) -> Self {
124+ Self {
154125 name,
155- } ) ;
126+ added : vec ! [ ] ,
127+ removed : vec ! [ ] ,
128+ changed : vec ! [ ] ,
129+ }
156130 }
157-
158- lints
159131}
160132
161133fn print_lint_warnings ( lint : & LintWarnings , truncate_after : usize ) {
162134 let name = & lint. name ;
163135 let html_id = to_html_id ( name) ;
164136
165137 // The additional anchor is added for non GH viewers that don't prefix ID's
166- println ! ( r#"## `{name}` <a id="user-content-{html_id}"/ >"# ) ;
138+ println ! ( r#"## `{name}` <a id="user-content-{html_id}"></a >"# ) ;
167139 println ! ( ) ;
168140
169141 print ! (
@@ -264,7 +236,7 @@ fn truncate<T>(list: &[T], truncate_after: usize) -> &[T] {
264236fn print_h3 ( lint : & str , title : & str ) {
265237 let html_id = to_html_id ( lint) ;
266238 // We have to use HTML here to be able to manually add an id.
267- println ! ( r#"### {title} <a id="user-content-{html_id}-{title}"/ >"# ) ;
239+ println ! ( r#"### {title} <a id="user-content-{html_id}-{title}"></a >"# ) ;
268240}
269241
270242/// GitHub's markdown parsers doesn't like IDs with `::` and `_`. This simplifies
0 commit comments