diff --git a/src/rustfmt_diff.rs b/src/rustfmt_diff.rs index f37ab5c16ef..d563e6eee3c 100644 --- a/src/rustfmt_diff.rs +++ b/src/rustfmt_diff.rs @@ -37,6 +37,43 @@ fn new(line_number: u32) -> Mismatch { } } +// This struct handles writing output to stdout and abstracts away the logic +// of printing in color, if it's possible in the executing environment. +pub struct OutputWriter { + terminal: Option>>, +} + +impl OutputWriter { + // Create a new OutputWriter instance based on the caller's preference + // for colorized output and the capabilities of the terminal. + pub fn new(color: Color) -> Self { + if let Some(t) = term::stdout() { + if use_colored_tty(color) && t.supports_color() { + return OutputWriter { terminal: Some(t) }; + } + } + OutputWriter { terminal: None } + } + + // Write output in the optionally specified color. The output is written + // in the specified color if this OutputWriter instance contains a + // Terminal in its `terminal` field. + pub fn writeln(&mut self, msg: &str, color: Option) { + match &mut self.terminal { + Some(ref mut t) => { + if let Some(color) = color { + t.fg(color).unwrap(); + } + writeln!(t, "{}", msg).unwrap(); + if color.is_some() { + t.reset().unwrap(); + } + } + None => println!("{}", msg), + } + } +} + // Produces a diff between the expected output and actual output of rustfmt. pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec { let mut line_number = 1; @@ -97,80 +134,24 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec Self { - match term::stdout() { - Some(ref t) if use_colored_tty(color) && t.supports_color() => PrintType::Fancy, - _ => PrintType::Basic, - } - } -} - pub fn print_diff(diff: Vec, get_section_title: F, color: Color) where F: Fn(u32) -> String, { - match PrintType::get(color) { - PrintType::Fancy => print_diff_fancy(diff, get_section_title, term::stdout().unwrap()), - PrintType::Basic => print_diff_basic(diff, get_section_title), - } -} + let mut writer = OutputWriter::new(color); -fn print_diff_fancy( - diff: Vec, - get_section_title: F, - mut t: Box>, -) where - F: Fn(u32) -> String, -{ for mismatch in diff { let title = get_section_title(mismatch.line_number); - writeln!(t, "{}", title).unwrap(); + writer.writeln(&format!("{}", title), None); for line in mismatch.lines { match line { - DiffLine::Context(ref str) => { - t.reset().unwrap(); - writeln!(t, " {}⏎", str).unwrap(); - } + DiffLine::Context(ref str) => writer.writeln(&format!(" {}⏎", str), None), DiffLine::Expected(ref str) => { - t.fg(term::color::GREEN).unwrap(); - writeln!(t, "+{}⏎", str).unwrap(); + writer.writeln(&format!("+{}⏎", str), Some(term::color::GREEN)) } DiffLine::Resulting(ref str) => { - t.fg(term::color::RED).unwrap(); - writeln!(t, "-{}⏎", str).unwrap(); - } - } - } - t.reset().unwrap(); - } -} - -pub fn print_diff_basic(diff: Vec, get_section_title: F) -where - F: Fn(u32) -> String, -{ - for mismatch in diff { - let title = get_section_title(mismatch.line_number); - println!("{}", title); - - for line in mismatch.lines { - match line { - DiffLine::Context(ref str) => { - println!(" {}⏎", str); - } - DiffLine::Expected(ref str) => { - println!("+{}⏎", str); - } - DiffLine::Resulting(ref str) => { - println!("-{}⏎", str); + writer.writeln(&format!("-{}⏎", str), Some(term::color::RED)) } } } diff --git a/tests/system.rs b/tests/system.rs index d99e1a4a4e2..0671a845b2e 100644 --- a/tests/system.rs +++ b/tests/system.rs @@ -106,10 +106,8 @@ fn verify_config_test_names() { // using only one or the other will cause the output order to differ when // `print_diff` selects the approach not used. fn write_message(msg: String) { - match PrintType::get(Color::Auto) { - PrintType::Fancy => writeln!(term::stdout().unwrap(), "{}", msg).unwrap(), - PrintType::Basic => println!("{}", msg), - } + let mut writer = OutputWriter::new(Color::Auto); + writer.writeln(&format!("{}", msg), None); } // Integration tests. The files in the tests/source are formatted and compared