@@ -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
@@ -172,9 +171,7 @@ pub fn gather_all() -> impl Iterator<Item = Lint> {
172171}
173172
174173fn 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 ( ) ;
174+ let content = fs:: read_to_string ( dir_entry. path ( ) ) . unwrap ( ) ;
178175 let mut filename = dir_entry. path ( ) . file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
179176 // If the lints are stored in mod.rs, we get the module name from
180177 // the containing directory:
@@ -209,7 +206,7 @@ fn lint_files() -> impl Iterator<Item = walkdir::DirEntry> {
209206 let path = clippy_project_root ( ) . join ( "clippy_lints/src" ) ;
210207 WalkDir :: new ( path)
211208 . into_iter ( )
212- . filter_map ( std :: result :: Result :: ok)
209+ . filter_map ( Result :: ok)
213210 . filter ( |f| f. path ( ) . extension ( ) == Some ( OsStr :: new ( "rs" ) ) )
214211}
215212
@@ -225,7 +222,6 @@ pub struct FileChange {
225222/// `path` is the relative path to the file on which you want to perform the replacement.
226223///
227224/// See `replace_region_in_text` for documentation of the other options.
228- #[ allow( clippy:: expect_fun_call) ]
229225pub fn replace_region_in_file < F > (
230226 path : & Path ,
231227 start : & str ,
@@ -235,22 +231,15 @@ pub fn replace_region_in_file<F>(
235231 replacements : F ,
236232) -> FileChange
237233where
238- F : Fn ( ) -> Vec < String > ,
234+ F : FnOnce ( ) -> Vec < String > ,
239235{
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" ) ;
236+ let contents = fs:: read_to_string ( path) . unwrap_or_else ( |e| panic ! ( "Cannot read from {}: {}" , path. display( ) , e) ) ;
245237 let file_change = replace_region_in_text ( & contents, start, end, replace_start, replacements) ;
246238
247239 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" ) ;
240+ if let Err ( e) = fs:: write ( path, file_change. new_lines . as_bytes ( ) ) {
241+ panic ! ( "Cannot write to {}: {}" , path. display( ) , e) ;
242+ }
254243 }
255244 file_change
256245}
@@ -273,31 +262,32 @@ where
273262///
274263/// ```
275264/// 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;
265+ /// let result =
266+ /// clippy_dev::replace_region_in_text(the_text, "replace_start", "replace_end", false, || {
267+ /// vec!["a different".to_string(), "text".to_string()]
268+ /// })
269+ /// .new_lines;
280270/// assert_eq!("replace_start\na different\ntext\nreplace_end", result);
281271/// ```
282272pub fn replace_region_in_text < F > ( text : & str , start : & str , end : & str , replace_start : bool , replacements : F ) -> FileChange
283273where
284- F : Fn ( ) -> Vec < String > ,
274+ F : FnOnce ( ) -> Vec < String > ,
285275{
286- let lines = text . lines ( ) ;
276+ let replace_it = replacements ( ) ;
287277 let mut in_old_region = false ;
288278 let mut found = false ;
289279 let mut new_lines = vec ! [ ] ;
290280 let start = Regex :: new ( start) . unwrap ( ) ;
291281 let end = Regex :: new ( end) . unwrap ( ) ;
292282
293- for line in lines . clone ( ) {
283+ for line in text . lines ( ) {
294284 if in_old_region {
295- if end. is_match ( & line) {
285+ if end. is_match ( line) {
296286 in_old_region = false ;
297- new_lines. extend ( replacements ( ) ) ;
287+ new_lines. extend ( replace_it . clone ( ) ) ;
298288 new_lines. push ( line. to_string ( ) ) ;
299289 }
300- } else if start. is_match ( & line) {
290+ } else if start. is_match ( line) {
301291 if !replace_start {
302292 new_lines. push ( line. to_string ( ) ) ;
303293 }
@@ -315,10 +305,12 @@ where
315305 eprintln ! ( "error: regex `{:?}` not found. You may have to update it." , start) ;
316306 }
317307
318- FileChange {
319- changed : lines . ne ( new_lines . clone ( ) ) ,
320- new_lines : new_lines . join ( " \n " ) ,
308+ let mut new_lines = new_lines . join ( " \n " ) ;
309+ if text . ends_with ( '\n' ) {
310+ new_lines. push ( '\n' ) ;
321311 }
312+ let changed = new_lines != text;
313+ FileChange { changed, new_lines }
322314}
323315
324316/// Returns the path to the Clippy project directory
0 commit comments