Skip to content

Commit 729f943

Browse files
committed
dev: Prefer fs::read* and improvement to replace text region
1 parent b5e6d6d commit 729f943

File tree

1 file changed

+23
-31
lines changed

1 file changed

+23
-31
lines changed

clippy_dev/src/lib.rs

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use regex::Regex;
66
use std::collections::HashMap;
77
use std::ffi::OsStr;
88
use std::fs;
9-
use std::io::prelude::*;
109
use std::path::{Path, PathBuf};
1110
use walkdir::WalkDir;
1211

@@ -172,9 +171,7 @@ pub fn gather_all() -> impl Iterator<Item = Lint> {
172171
}
173172

174173
fn 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)]
229225
pub 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
237233
where
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
/// ```
282272
pub fn replace_region_in_text<F>(text: &str, start: &str, end: &str, replace_start: bool, replacements: F) -> FileChange
283273
where
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

Comments
 (0)