@@ -6,7 +6,6 @@ use regex::Regex;
66use std:: collections:: HashMap ;
77use std:: ffi:: OsStr ;
88use std:: fs;
9- use std:: io:: prelude:: * ;
109use std:: path:: { Path , PathBuf } ;
1110use walkdir:: WalkDir ;
1211
@@ -31,9 +30,10 @@ lazy_static! {
3130 )
3231 . unwrap( ) ;
3332 static ref NL_ESCAPE_RE : Regex = Regex :: new( r#"\\\n\s*"# ) . unwrap( ) ;
34- pub static ref DOCS_LINK : String = "https://rust-lang.github.io/rust-clippy/master/index.html" . to_string( ) ;
3533}
3634
35+ pub static DOCS_LINK : & str = "https://rust-lang.github.io/rust-clippy/master/index.html" ;
36+
3737/// Lint data parsed from the Clippy source code.
3838#[ derive( Clone , PartialEq , Debug ) ]
3939pub struct Lint {
@@ -121,7 +121,7 @@ pub fn gen_changelog_lint_list(lints: Vec<Lint>) -> Vec<String> {
121121 if l. is_internal ( ) {
122122 None
123123 } else {
124- Some ( format ! ( "[`{}`]: {}#{}" , l. name, DOCS_LINK . clone ( ) , l. name) )
124+ Some ( format ! ( "[`{}`]: {}#{}" , l. name, DOCS_LINK , l. name) )
125125 }
126126 } )
127127 . collect ( )
@@ -172,9 +172,7 @@ pub fn gather_all() -> impl Iterator<Item = Lint> {
172172}
173173
174174fn gather_from_file ( dir_entry : & walkdir:: DirEntry ) -> impl Iterator < Item = Lint > {
175- let mut file = fs:: File :: open ( dir_entry. path ( ) ) . unwrap ( ) ;
176- let mut content = String :: new ( ) ;
177- file. read_to_string ( & mut content) . unwrap ( ) ;
175+ let content = fs:: read_to_string ( dir_entry. path ( ) ) . unwrap ( ) ;
178176 let mut filename = dir_entry. path ( ) . file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
179177 // If the lints are stored in mod.rs, we get the module name from
180178 // the containing directory:
@@ -209,7 +207,7 @@ fn lint_files() -> impl Iterator<Item = walkdir::DirEntry> {
209207 let path = clippy_project_root ( ) . join ( "clippy_lints/src" ) ;
210208 WalkDir :: new ( path)
211209 . into_iter ( )
212- . filter_map ( std :: result :: Result :: ok)
210+ . filter_map ( Result :: ok)
213211 . filter ( |f| f. path ( ) . extension ( ) == Some ( OsStr :: new ( "rs" ) ) )
214212}
215213
@@ -225,7 +223,6 @@ pub struct FileChange {
225223/// `path` is the relative path to the file on which you want to perform the replacement.
226224///
227225/// See `replace_region_in_text` for documentation of the other options.
228- #[ allow( clippy:: expect_fun_call) ]
229226pub fn replace_region_in_file < F > (
230227 path : & Path ,
231228 start : & str ,
@@ -235,22 +232,15 @@ pub fn replace_region_in_file<F>(
235232 replacements : F ,
236233) -> FileChange
237234where
238- F : Fn ( ) -> Vec < String > ,
235+ F : FnOnce ( ) -> Vec < String > ,
239236{
240- let path = clippy_project_root ( ) . join ( path) ;
241- let mut f = fs:: File :: open ( & path) . expect ( & format ! ( "File not found: {}" , path. to_string_lossy( ) ) ) ;
242- let mut contents = String :: new ( ) ;
243- f. read_to_string ( & mut contents)
244- . expect ( "Something went wrong reading the file" ) ;
237+ let contents = fs:: read_to_string ( path) . unwrap_or_else ( |e| panic ! ( "Cannot read from {}: {}" , path. display( ) , e) ) ;
245238 let file_change = replace_region_in_text ( & contents, start, end, replace_start, replacements) ;
246239
247240 if write_back {
248- let mut f = fs:: File :: create ( & path) . expect ( & format ! ( "File not found: {}" , path. to_string_lossy( ) ) ) ;
249- f. write_all ( file_change. new_lines . as_bytes ( ) )
250- . expect ( "Unable to write file" ) ;
251- // Ensure we write the changes with a trailing newline so that
252- // the file has the proper line endings.
253- f. write_all ( b"\n " ) . expect ( "Unable to write file" ) ;
241+ if let Err ( e) = fs:: write ( path, file_change. new_lines . as_bytes ( ) ) {
242+ panic ! ( "Cannot write to {}: {}" , path. display( ) , e) ;
243+ }
254244 }
255245 file_change
256246}
@@ -273,31 +263,32 @@ where
273263///
274264/// ```
275265/// let the_text = "replace_start\nsome text\nthat will be replaced\nreplace_end";
276- /// let result = clippy_dev::replace_region_in_text(the_text, r#"replace_start"#, r#"replace_end"#, false, || {
277- /// vec!["a different".to_string(), "text".to_string()]
278- /// })
279- /// .new_lines;
266+ /// let result =
267+ /// clippy_dev::replace_region_in_text(the_text, "replace_start", "replace_end", false, || {
268+ /// vec!["a different".to_string(), "text".to_string()]
269+ /// })
270+ /// .new_lines;
280271/// assert_eq!("replace_start\na different\ntext\nreplace_end", result);
281272/// ```
282273pub fn replace_region_in_text < F > ( text : & str , start : & str , end : & str , replace_start : bool , replacements : F ) -> FileChange
283274where
284- F : Fn ( ) -> Vec < String > ,
275+ F : FnOnce ( ) -> Vec < String > ,
285276{
286- let lines = text . lines ( ) ;
277+ let replace_it = replacements ( ) ;
287278 let mut in_old_region = false ;
288279 let mut found = false ;
289280 let mut new_lines = vec ! [ ] ;
290281 let start = Regex :: new ( start) . unwrap ( ) ;
291282 let end = Regex :: new ( end) . unwrap ( ) ;
292283
293- for line in lines . clone ( ) {
284+ for line in text . lines ( ) {
294285 if in_old_region {
295- if end. is_match ( & line) {
286+ if end. is_match ( line) {
296287 in_old_region = false ;
297- new_lines. extend ( replacements ( ) ) ;
288+ new_lines. extend ( replace_it . clone ( ) ) ;
298289 new_lines. push ( line. to_string ( ) ) ;
299290 }
300- } else if start. is_match ( & line) {
291+ } else if start. is_match ( line) {
301292 if !replace_start {
302293 new_lines. push ( line. to_string ( ) ) ;
303294 }
@@ -315,10 +306,12 @@ where
315306 eprintln ! ( "error: regex `{:?}` not found. You may have to update it." , start) ;
316307 }
317308
318- FileChange {
319- changed : lines . ne ( new_lines . clone ( ) ) ,
320- new_lines : new_lines . join ( " \n " ) ,
309+ let mut new_lines = new_lines . join ( " \n " ) ;
310+ if text . ends_with ( '\n' ) {
311+ new_lines. push ( '\n' ) ;
321312 }
313+ let changed = new_lines != text;
314+ FileChange { changed, new_lines }
322315}
323316
324317/// Returns the path to the Clippy project directory
0 commit comments