use std::collections::HashMap;
use std::fs::{self, File};
-use std::io::{self, Write, Read, stdout};
+use std::io::{self, Write, Read, stdout, BufWriter};
-use WriteMode;
-use config::{NewlineStyle, Config};
-use rustfmt_diff::{make_diff, print_diff};
+use config::{NewlineStyle, Config, WriteMode};
+use rustfmt_diff::{make_diff, print_diff, Mismatch};
+use checkstyle::{output_header, output_footer, output_checkstyle_file};
// A map of the files of a crate, with their new content
pub type FileMap = HashMap<String, StringBuffer>;
}
}
-pub fn write_all_files(file_map: &FileMap,
- mode: WriteMode,
- config: &Config)
- -> Result<(HashMap<String, String>), io::Error> {
- let mut result = HashMap::new();
+pub fn write_all_files<T>(file_map: &FileMap, out: &mut T, config: &Config) -> Result<(), io::Error>
+ where T: Write
+{
+ output_header(out, config.write_mode).ok();
for filename in file_map.keys() {
- let one_result = try!(write_file(&file_map[filename], filename, mode, config));
- if let Some(r) = one_result {
- result.insert(filename.clone(), r);
- }
+ try!(write_file(&file_map[filename], filename, out, config));
}
+ output_footer(out, config.write_mode).ok();
- Ok(result)
+ Ok(())
}
-pub fn write_file(text: &StringBuffer,
- filename: &str,
- mode: WriteMode,
- config: &Config)
- -> Result<Option<String>, io::Error> {
- // prints all newlines either as `\n` or as `\r\n`
- fn write_system_newlines<T>(mut writer: T,
+// Prints all newlines either as `\n` or as `\r\n`.
+pub fn write_system_newlines<T>(writer: T,
text: &StringBuffer,
config: &Config)
-> Result<(), io::Error>
- where T: Write
- {
- let style = if config.newline_style == NewlineStyle::Native {
- if cfg!(windows) {
- NewlineStyle::Windows
- } else {
- NewlineStyle::Unix
- }
+ where T: Write
+{
+ // Buffer output, since we're writing a since char at a time.
+ let mut writer = BufWriter::new(writer);
+
+ let style = if config.newline_style == NewlineStyle::Native {
+ if cfg!(windows) {
+ NewlineStyle::Windows
} else {
- config.newline_style
- };
-
- match style {
- NewlineStyle::Unix => write!(writer, "{}", text),
- NewlineStyle::Windows => {
- for (c, _) in text.chars() {
- match c {
- '\n' => try!(write!(writer, "\r\n")),
- '\r' => continue,
- c => try!(write!(writer, "{}", c)),
- }
+ NewlineStyle::Unix
+ }
+ } else {
+ config.newline_style
+ };
+
+ match style {
+ NewlineStyle::Unix => write!(writer, "{}", text),
+ NewlineStyle::Windows => {
+ for (c, _) in text.chars() {
+ match c {
+ '\n' => try!(write!(writer, "\r\n")),
+ '\r' => continue,
+ c => try!(write!(writer, "{}", c)),
}
- Ok(())
}
- NewlineStyle::Native => unreachable!(),
+ Ok(())
}
+ NewlineStyle::Native => unreachable!(),
}
+}
+
+pub fn write_file<T>(text: &StringBuffer,
+ filename: &str,
+ out: &mut T,
+ config: &Config)
+ -> Result<Option<String>, io::Error>
+ where T: Write
+{
fn source_and_formatted_text(text: &StringBuffer,
filename: &str,
Ok((ori_text, fmt_text))
}
- match mode {
+ fn create_diff(filename: &str,
+ text: &StringBuffer,
+ config: &Config)
+ -> Result<Vec<Mismatch>, io::Error> {
+ let (ori, fmt) = try!(source_and_formatted_text(text, filename, config));
+ Ok(make_diff(&ori, &fmt, 3))
+ }
+
+ match config.write_mode {
WriteMode::Replace => {
if let Ok((ori, fmt)) = source_and_formatted_text(text, filename, config) {
if fmt != ori {
let file = try!(File::create(filename));
try!(write_system_newlines(file, text, config));
}
- WriteMode::NewFile(extn) => {
- let filename = filename.to_owned() + "." + extn;
- let file = try!(File::create(&filename));
- try!(write_system_newlines(file, text, config));
- }
WriteMode::Plain => {
let stdout = stdout();
let stdout = stdout.lock();
|line_num| format!("\nDiff at line {}:", line_num));
}
}
- WriteMode::Return => {
- // io::Write is not implemented for String, working around with
- // Vec<u8>
- let mut v = Vec::new();
- try!(write_system_newlines(&mut v, text, config));
- // won't panic, we are writing correct utf8
- return Ok(Some(String::from_utf8(v).unwrap()));
+ WriteMode::Checkstyle => {
+ let diff = try!(create_diff(filename, text, config));
+ try!(output_checkstyle_file(out, filename, diff));
}
}