Skip to content

Commit 6b00b8b

Browse files
committed
Move newline logic inside the formatting process.
Why?: - Conceptually it sounds right - Absolutely all write modes where doing it anyway - It was done several times in some in case - It greatly simplify the code
1 parent 8c32a9d commit 6b00b8b

File tree

3 files changed

+70
-111
lines changed

3 files changed

+70
-111
lines changed

src/filemap.rs

Lines changed: 36 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@
1010

1111
// TODO: add tests
1212

13-
use std::fs::{self, File};
14-
use std::io::{self, BufWriter, Read, Write};
15-
use std::path::Path;
13+
use std::fs;
14+
use std::io::{self, Write};
1615

1716
use checkstyle::output_checkstyle_file;
18-
use config::{Config, EmitMode, FileName, NewlineStyle, Verbosity};
19-
use rustfmt_diff::{make_diff, output_modified, print_diff, Mismatch};
17+
use config::{Config, EmitMode, FileName, Verbosity};
18+
use rustfmt_diff::{make_diff, output_modified, print_diff};
2019

2120
#[cfg(test)]
2221
use FileRecord;
@@ -48,72 +47,15 @@ where
4847
Ok(())
4948
}
5049

51-
// Prints all newlines either as `\n` or as `\r\n`.
52-
pub fn write_system_newlines<T>(writer: T, text: &str, config: &Config) -> Result<(), io::Error>
53-
where
54-
T: Write,
55-
{
56-
// Buffer output, since we're writing a since char at a time.
57-
let mut writer = BufWriter::new(writer);
58-
59-
let style = if config.newline_style() == NewlineStyle::Native {
60-
if cfg!(windows) {
61-
NewlineStyle::Windows
62-
} else {
63-
NewlineStyle::Unix
64-
}
65-
} else {
66-
config.newline_style()
67-
};
68-
69-
match style {
70-
NewlineStyle::Unix => write!(writer, "{}", text),
71-
NewlineStyle::Windows => {
72-
for c in text.chars() {
73-
match c {
74-
'\n' => write!(writer, "\r\n")?,
75-
'\r' => continue,
76-
c => write!(writer, "{}", c)?,
77-
}
78-
}
79-
Ok(())
80-
}
81-
NewlineStyle::Native => unreachable!(),
82-
}
83-
}
84-
8550
pub fn write_file<T>(
86-
text: &str,
51+
formatted_text: &str,
8752
filename: &FileName,
8853
out: &mut T,
8954
config: &Config,
9055
) -> Result<bool, io::Error>
9156
where
9257
T: Write,
9358
{
94-
fn source_and_formatted_text(
95-
text: &str,
96-
filename: &Path,
97-
config: &Config,
98-
) -> Result<(String, String), io::Error> {
99-
let mut f = File::open(filename)?;
100-
let mut ori_text = String::new();
101-
f.read_to_string(&mut ori_text)?;
102-
let mut v = Vec::new();
103-
write_system_newlines(&mut v, text, config)?;
104-
let fmt_text = String::from_utf8(v).unwrap();
105-
Ok((ori_text, fmt_text))
106-
}
107-
108-
fn create_diff(
109-
filename: &Path,
110-
text: &str,
111-
config: &Config,
112-
) -> Result<Vec<Mismatch>, io::Error> {
113-
let (ori, fmt) = source_and_formatted_text(text, filename, config)?;
114-
Ok(make_diff(&ori, &fmt, 3))
115-
}
116-
11759
let filename_to_path = || match *filename {
11860
FileName::Real(ref path) => path,
11961
_ => panic!("cannot format `{}` and emit to files", filename),
@@ -122,65 +64,58 @@ where
12264
match config.emit_mode() {
12365
EmitMode::Files if config.make_backup() => {
12466
let filename = filename_to_path();
125-
if let Ok((ori, fmt)) = source_and_formatted_text(text, filename, config) {
126-
if fmt != ori {
127-
// Do a little dance to make writing safer - write to a temp file
128-
// rename the original to a .bk, then rename the temp file to the
129-
// original.
130-
let tmp_name = filename.with_extension("tmp");
131-
let bk_name = filename.with_extension("bk");
132-
{
133-
// Write text to temp file
134-
let tmp_file = File::create(&tmp_name)?;
135-
write_system_newlines(tmp_file, text, config)?;
136-
}
137-
138-
fs::rename(filename, bk_name)?;
139-
fs::rename(tmp_name, filename)?;
140-
}
67+
let ori = fs::read_to_string(filename)?;
68+
if ori != formatted_text {
69+
// Do a little dance to make writing safer - write to a temp file
70+
// rename the original to a .bk, then rename the temp file to the
71+
// original.
72+
let tmp_name = filename.with_extension("tmp");
73+
let bk_name = filename.with_extension("bk");
74+
75+
fs::write(&tmp_name, formatted_text)?;
76+
fs::rename(filename, bk_name)?;
77+
fs::rename(tmp_name, filename)?;
14178
}
14279
}
14380
EmitMode::Files => {
14481
// Write text directly over original file if there is a diff.
14582
let filename = filename_to_path();
146-
let (source, formatted) = source_and_formatted_text(text, filename, config)?;
147-
if source != formatted {
148-
let file = File::create(filename)?;
149-
write_system_newlines(file, text, config)?;
83+
let ori = fs::read_to_string(filename)?;
84+
if ori != formatted_text {
85+
fs::write(filename, formatted_text)?;
15086
}
15187
}
15288
EmitMode::Stdout | EmitMode::Coverage => {
15389
if config.verbose() != Verbosity::Quiet {
15490
println!("{}:\n", filename);
15591
}
156-
write_system_newlines(out, text, config)?;
92+
write!(out, "{}", formatted_text)?;
15793
}
15894
EmitMode::ModifiedLines => {
15995
let filename = filename_to_path();
160-
if let Ok((ori, fmt)) = source_and_formatted_text(text, filename, config) {
161-
let mismatch = make_diff(&ori, &fmt, 0);
162-
let has_diff = !mismatch.is_empty();
163-
output_modified(out, mismatch);
164-
return Ok(has_diff);
165-
}
96+
let ori = fs::read_to_string(filename)?;
97+
let mismatch = make_diff(&ori, formatted_text, 0);
98+
let has_diff = !mismatch.is_empty();
99+
output_modified(out, mismatch);
100+
return Ok(has_diff);
166101
}
167102
EmitMode::Checkstyle => {
168103
let filename = filename_to_path();
169-
let diff = create_diff(filename, text, config)?;
104+
let ori = fs::read_to_string(filename)?;
105+
let diff = make_diff(&ori, formatted_text, 3);
170106
output_checkstyle_file(out, filename, diff)?;
171107
}
172108
EmitMode::Diff => {
173109
let filename = filename_to_path();
174-
if let Ok((ori, fmt)) = source_and_formatted_text(text, filename, config) {
175-
let mismatch = make_diff(&ori, &fmt, 3);
176-
let has_diff = !mismatch.is_empty();
177-
print_diff(
178-
mismatch,
179-
|line_num| format!("Diff in {} at line {}:", filename.display(), line_num),
180-
config,
181-
);
182-
return Ok(has_diff);
183-
}
110+
let ori = fs::read_to_string(filename)?;
111+
let mismatch = make_diff(&ori, formatted_text, 3);
112+
let has_diff = !mismatch.is_empty();
113+
print_diff(
114+
mismatch,
115+
|line_num| format!("Diff in {} at line {}:", filename.display(), line_num),
116+
config,
117+
);
118+
return Ok(has_diff);
184119
}
185120
}
186121

src/lib.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ use visitor::{FmtVisitor, SnippetProvider};
6060
pub use checkstyle::{footer as checkstyle_footer, header as checkstyle_header};
6161
pub use config::summary::Summary;
6262
pub use config::{
63-
load_config, CliOptions, Color, Config, EmitMode, FileLines, FileName, Range, Verbosity,
63+
load_config, CliOptions, Color, Config, EmitMode, FileLines, FileName, NewlineStyle, Range,
64+
Verbosity,
6465
};
6566

6667
#[macro_use]
@@ -877,6 +878,7 @@ fn format_input_inner<T: Write>(
877878
filemap::append_newline(file);
878879

879880
format_lines(file, file_name, skipped_range, config, report);
881+
replace_with_system_newlines(file, config);
880882

881883
if let Some(ref mut out) = out {
882884
return filemap::write_file(file, file_name, out, config);
@@ -929,6 +931,34 @@ fn format_input_inner<T: Write>(
929931
}
930932
}
931933

934+
pub fn replace_with_system_newlines(text: &mut String, config: &Config) -> () {
935+
let style = if config.newline_style() == NewlineStyle::Native {
936+
if cfg!(windows) {
937+
NewlineStyle::Windows
938+
} else {
939+
NewlineStyle::Unix
940+
}
941+
} else {
942+
config.newline_style()
943+
};
944+
945+
match style {
946+
NewlineStyle::Unix => return,
947+
NewlineStyle::Windows => {
948+
let mut transformed = String::with_capacity(text.capacity());
949+
for c in text.chars() {
950+
match c {
951+
'\n' => transformed.push_str("\r\n"),
952+
'\r' => continue,
953+
c => transformed.push(c),
954+
}
955+
}
956+
*text = transformed;
957+
}
958+
NewlineStyle::Native => unreachable!(),
959+
}
960+
}
961+
932962
/// A single span of changed lines, with 0 or more removed lines
933963
/// and a vector of 0 or more inserted lines.
934964
#[derive(Debug, PartialEq, Eq)]

src/test/mod.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use std::str::Chars;
2222

2323
use config::summary::Summary;
2424
use config::{Color, Config, ReportTactic};
25-
use filemap::write_system_newlines;
2625
use rustfmt_diff::*;
2726
use *;
2827

@@ -401,14 +400,9 @@ fn idempotent_check(
401400
}
402401

403402
let mut write_result = HashMap::new();
404-
for &(ref filename, ref text) in &file_map {
405-
let mut v = Vec::new();
406-
// Won't panic, as we're not doing any IO.
407-
write_system_newlines(&mut v, text, &config).unwrap();
408-
// Won't panic, we are writing correct utf8.
409-
let one_result = String::from_utf8(v).unwrap();
410-
if let FileName::Real(ref filename) = *filename {
411-
write_result.insert(filename.to_owned(), one_result);
403+
for (filename, text) in file_map {
404+
if let FileName::Real(ref filename) = filename {
405+
write_result.insert(filename.to_owned(), text);
412406
}
413407
}
414408

0 commit comments

Comments
 (0)