use std::panic;
use diff_match_patch_rs::{Compat, DiffMatchPatch, PatchInput};
use reconcile_text::{BuiltinTokenizer, reconcile};
fn dmp_merge(parent: &str, left: &str, right: &str) -> Option<String> {
let parent = parent.to_owned();
let left = left.to_owned();
let right = right.to_owned();
panic::catch_unwind(|| {
let dmp = DiffMatchPatch::new();
let diffs = dmp.diff_main::<Compat>(&parent, &left).ok()?;
let patches = dmp
.patch_make(PatchInput::new_text_diffs(&parent, &diffs))
.ok()?;
let (result, _) = dmp.patch_apply(&patches, &right).ok()?;
Some(result)
})
.ok()
.flatten()
}
fn try_merge(parent: &str, left: &str, right: &str) {
let dmp_result = dmp_merge(parent, left, right);
let reconcile_result = reconcile(
parent,
&left.into(),
&right.into(),
&*BuiltinTokenizer::Word,
)
.apply()
.text();
println!("Parent: {parent:?}");
println!("Left: {left:?}");
println!("Right: {right:?}");
println!();
match dmp_result {
Some(r) => println!("diff-match-patch: {r:?}"),
None => println!("diff-match-patch: <panic or error>"),
}
println!("reconcile-text: {reconcile_result:?}");
println!();
}
fn main() {
println!("── Example 1: adjacent edits ──");
try_merge(
"old(!) broken code",
"new improved code",
"old(!) working code",
);
println!("── Example 2: sentence lost ──");
try_merge(
"We used the existing parsing approach for processing. The output was saved to the \
database.",
"We used the existing parsing approach for processing. Always validate the schema! The \
output was saved to the database.",
"We adopted a brand new analysis pipeline for execution. The results were written to \
cloud storage.",
);
}