extern crate difference;
use ansi_term::Colour::{Green, Red};
use ansi_term::Style;
use difference::{Changeset, Difference};
use std::env;
pub fn print_diff(cs: &Changeset) -> std::io::Result<()> {
let Changeset { diffs, .. } = cs;
let red_fg;
let green_fg;
match env::var("TERM").as_ref().map(String::as_str) {
Ok("dumb") | Err(_) => {
red_fg = Style::new();
green_fg = Style::new();
}
Ok(_) => {
red_fg = Style::new().fg(Red);
green_fg = Style::new().fg(Green);
}
}
for diff in diffs {
match diff {
Difference::Same(x) => {
for line in x.lines() {
println!(" {}", line);
}
}
Difference::Add(x) => {
for line in x.lines() {
println!("{}{}", green_fg.paint("+"), green_fg.paint(line));
}
}
Difference::Rem(x) => {
for line in x.lines() {
println!("{}{}", red_fg.paint("-"), red_fg.paint(line));
}
}
}
}
Ok(())
}
#[macro_export]
macro_rules! assert_diff {
($orig:expr, $edit:expr) => {{ assert_diff!($orig, $edit, "\n", 0) }};
($orig:expr, $edit:expr, $split:expr, $expected:expr) => {{
let orig = $orig;
let edit = $edit;
let changeset = difference::Changeset::new(orig, edit, &($split));
if changeset.distance != $expected {
if let Err(e) = $crate::diff::print_diff(&changeset) {
eprintln!("{}", e);
}
panic!(
"assertion failed: edit distance was {}, not {}, see diff above",
changeset.distance,
&($expected)
)
}
}};
}