// Line-based diff computation.
use std::fs::File;
use std::io::{BufRead, BufReader};
struct LineDiff<'a> {
s1: &'a [String],
s2: &'a [String],
}
impl<'a> LineDiff<'a> {
fn new(s1: &'a [String], s2: &'a [String]) -> Self {
Self { s1: s1, s2: s2 }
}
}
impl<'a> diffs::Diff for LineDiff<'a> {
type Error = ();
fn equal(&mut self, old: usize, _new: usize, len: usize) -> Result<(), Self::Error> {
for l in &self.s1[old..old + len] {
println!("= {}", l);
}
Ok(())
}
fn delete(&mut self, o: usize, len: usize, _new: usize) -> Result<(), ()> {
for l in &self.s1[o..o + len] {
println!("< {}", l);
}
Ok(())
}
fn insert(&mut self, _o: usize, n: usize, len: usize) -> Result<(), ()> {
for l in &self.s2[n..n + len] {
println!("> {}", l);
}
Ok(())
}
}
pub fn main() {
let args: Vec<_> = std::env::args().collect();
if args.len() != 4 {
println!(
"Usage: diff <algorithm> <file1> <file2>\nwhere <algorithm> is myers, or patience."
);
return;
}
let (algorithm, file1, file2) = (&args[1], &args[2], &args[3]);
let l1: Vec<_> = BufReader::new(File::open(file1).unwrap())
.lines()
.collect::<Result<_, _>>()
.unwrap();
let l2: Vec<_> = BufReader::new(File::open(file2).unwrap())
.lines()
.collect::<Result<_, _>>()
.unwrap();
let mut differ = LineDiff::new(&l1, &l2);
if algorithm == "myers" {
diffs::myers::diff(&mut differ, &l1, 0, l1.len(), &l2, 0, l2.len()).unwrap();
} else if algorithm == "patience" {
diffs::patience::diff(&mut differ, &l1, 0, l1.len(), &l2, 0, l2.len()).unwrap();
} else {
println!("Invalid algorithm.");
return;
}
}