#![crate_name = "text_diff"]
#![doc(html_root_url = "https://johannhof.github.io/text-diff.rs/")]
#![deny(missing_docs)]
mod lcs;
mod merge;
use lcs::lcs;
use merge::merge;
#[derive(PartialEq, Debug)]
pub enum Difference {
Same(String),
Add(String),
Rem(String)
}
pub fn diff(orig: &str, edit: &str, split: &str) -> (i32, Vec<Difference>) {
let (dist, common) = lcs(orig, edit, split);
(dist, merge(orig, edit, &common, split))
}
pub fn assert_diff(orig: &str, edit: &str, split: &str, expected: i32) {
let (d, _) = diff(orig, edit, split);
if d != expected {
print_diff(orig, edit, split);
panic!("assertion failed: edit distance between {:?} and {:?} is {} and not {}, see diffset above"
, orig, edit, d, expected)
}
}
pub fn print_diff(orig: &str, edit: &str, split: &str) {
let (_, changeset) = diff(orig, edit, split);
let mut ret = String::new();
for seq in changeset {
match seq {
Difference::Same(ref x) => {
ret.push_str(x);
ret.push_str(split);
},
Difference::Add(ref x) => {
ret.push_str("\x1B[92m");
ret.push_str(x);
ret.push_str("\x1B[0m");
ret.push_str(split);
},
Difference::Rem(ref x) => {
ret.push_str("\x1B[91m");
ret.push_str(x);
ret.push_str("\x1B[0m");
ret.push_str(split);
}
}
}
println!("{}", ret);
}
#[test]
fn test_diff() {
let text1 = "Roses are red, violets are blue,\n\
I wrote this library,\n\
just for you.\n\
(It's true).";
let text2 = "Roses are red, violets are blue,\n\
I wrote this documentation,\n\
just for you.\n\
(It's quite true).";
let (dist, changeset) = diff(text1, text2, "\n");
assert_eq!(dist, 4);
assert_eq!(changeset, vec![
Difference::Same("Roses are red, violets are blue,".to_string()),
Difference::Rem("I wrote this library,".to_string()),
Difference::Add("I wrote this documentation,".to_string()),
Difference::Same("just for you.".to_string()),
Difference::Rem("(It's true).".to_string()),
Difference::Add("(It's quite true).".to_string())
]);
}
#[test]
#[should_panic]
fn test_assert_diff_panic() {
let text1 = "Roses are red, violets are blue,\n\
I wrote this library,\n\
just for you.\n\
(It's true).";
let text2 = "Roses are red, violets are blue,\n\
I wrote this documentation,\n\
just for you.\n\
(It's quite true).";
assert_diff(text1, text2, "\n'", 0);
}
#[test]
fn test_assert_diff() {
let text1 = "Roses are red, violets are blue";
let text2 = "Roses are green, violets are blue";
assert_diff(text1, text2, " ", 2);
}