use std::collections::VecDeque;
use diff;
use term;
+use std::io;
+#[derive(Debug, PartialEq)]
pub enum DiffLine {
Context(String),
Expected(String),
Resulting(String),
}
+#[derive(Debug, PartialEq)]
pub struct Mismatch {
pub line_number: u32,
pub lines: Vec<DiffLine>,
impl Mismatch {
fn new(line_number: u32) -> Mismatch {
- Mismatch { line_number: line_number, lines: Vec::new() }
+ Mismatch {
+ line_number: line_number,
+ lines: Vec::new(),
+ }
}
}
pub fn print_diff<F>(diff: Vec<Mismatch>, get_section_title: F)
where F: Fn(u32) -> String
{
- let mut t = term::stdout().unwrap();
+ match term::stdout() {
+ Some(ref t) if isatty() && t.supports_color() => {
+ print_diff_fancy(diff, get_section_title, term::stdout().unwrap())
+ }
+ _ => print_diff_basic(diff, get_section_title),
+ }
+
+ // isatty shamelessly adapted from cargo.
+ #[cfg(unix)]
+ fn isatty() -> bool {
+ extern crate libc;
+
+ unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
+ }
+ #[cfg(windows)]
+ fn isatty() -> bool {
+ extern crate kernel32;
+ extern crate winapi;
+
+ unsafe {
+ let handle = kernel32::GetStdHandle(winapi::winbase::STD_OUTPUT_HANDLE);
+ let mut out = 0;
+ kernel32::GetConsoleMode(handle, &mut out) != 0
+ }
+ }
+}
+
+fn print_diff_fancy<F>(diff: Vec<Mismatch>,
+ get_section_title: F,
+ mut t: Box<term::Terminal<Output = io::Stdout>>)
+ where F: Fn(u32) -> String
+{
for mismatch in diff {
- t.fg(term::color::BRIGHT_WHITE).unwrap();
let title = get_section_title(mismatch.line_number);
writeln!(t, "{}", title).unwrap();
for line in mismatch.lines {
match line {
DiffLine::Context(ref str) => {
- t.fg(term::color::WHITE).unwrap();
+ t.reset().unwrap();
writeln!(t, " {}⏎", str).unwrap();
}
DiffLine::Expected(ref str) => {
}
}
}
+ t.reset().unwrap();
+ }
+}
+
+pub fn print_diff_basic<F>(diff: Vec<Mismatch>, 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);
+ }
+ }
+ }
}
- t.reset().unwrap();
}