delta/
delta.rs

1use diff_match_patch_rs::{DiffMatchPatch, Efficient, Error, PatchInput};
2
3/// An example flow of the effitient mode
4/// This demo will cover creating a diff of two texts and then `patching` it back to get the original text
5///
6// This is the source text
7const TXT_OLD: &str = "I am the very model of a modern Major-General,
8I've information vegetable, animal, and mineral,
9I know the kings of England, and I quote the fights historical,
10From Marathon to Waterloo, in order categorical.
11
12Let's start with some basics 😊. We've got your standard smiley face 🙂, your sad face â˜šī¸, and your angry face 😠. But wait, there's more! 🤩 We've also got some more complex emotions like 😍, 🤤, and 🚀. And let's not forget about the classics: 😉, 👍, and 👏.";
13
14// Let's assume this to be the text that was editted from the source text
15const TXT_NEW: &str = "I am the very model of a cartoon individual,
16My animation's comical, unusual, and whimsical,
17I'm quite adept at funny gags, comedic theory I have read,
18From wicked puns and stupid jokes to anvils that drop on your head.
19
20Now, let's explore some emotional extremes 🌊. We've got your ecstatic face 🤩, your devastated face 😭, and your utterly confused face đŸ¤¯. But that's not all! 🤔 We've also got some subtle emotions like 😐, 🙃, and 👀.";
21
22// An example of a function that creates a diff and returns a set of patches serialized
23fn at_source() -> Result<String, Error> {
24    // initializing the module
25    let dmp = DiffMatchPatch::new();
26
27    // create a list of diffs
28    let diffs = dmp.diff_main::<Efficient>(TXT_OLD, TXT_NEW)?;
29
30    // When dealing with large text blocks and if you want to transmit this diff, `delta` will give you a minimal over the air representation of diffs
31    // We'll use this delta string to recreate `diffs` at the destination and then create patches to apply
32    let delta = dmp.diff_to_delta(&diffs)?;
33
34    // lets see how our delta looks
35    println!("{delta:?}");
36    // You should see something like this
37    // =25\t-1\t+carto\t=1\t-3\t=2\t-8\t+i\t=1\t-2\t+dividu\t=4\t-4\t+My\t=1\t-1\t+a\t=1\t-3\t+i\t=6\t+'s\t=1\t-5\t+comic\t=1\t-1\t=1\t-1\t=2\t-1\t+u\t=1\t-2\t+usu\t=8\t+whi\t=1\t+s\t=1\t-3\t+c\t=5\t+'m\t=1\t-5\t+qui\t=1\t-1\t=2\t-13\t=1\t-1\t=1\t-1\t+ept\t=2\t+t fu\t=1\t-1\t+ny\t=1\t-1\t+gags,\t=1\t-2\t+c\t=1\t-1\t+m\t=1\t+dic\t=4\t+ory\t=1\t-6\t+I\t=2\t-4\t+ave \t=1\t-2\t+e\t=1\t-1\t+d\t=7\t-1\t+wicked puns \t=1\t-2\t+nd s\t=1\t-1\t+upid j\t=1\t-1\t+kes\t=4\t-1\t+anvils th\t=2\t-1\t+ d\t=1\t-1\t=1\t+p \t=1\t-3\t=2\t+y\t=1\t-3\t+u\t=2\t-3\t+h\t=1\t-5\t=1\t-1\t+d\t=3\t-1\t+Now, l\t=5\t-3\t+explo\t=1\t-6\t+e\t=6\t-3\t+emot\t=1\t-1\t+onal extreme\t=4\t-1\t+%8C\t=18\t+ec\t=3\t-8\t+t\t=1\t-3\t+c\t=8\t-2\t+%A4%A9\t=7\t+deva\t=1\t+t\t=1\t+te\t=7\t-1\t+%F0%9F\t=1\t-4\t+%AD\t=11\t-3\t+utte\t=1\t+l\t=2\t+confused \t=7\t-2\t+%A4%AF\t=6\t-1\t+th\t=1\t-1\t=1\t-7\t=3\t-1\t+n\t=1\t-2\t+t all\t=5\t-1\t+%94\t=21\t-9\t+subt\t=2\t-1\t=18\t-64\t+%90\t=4\t-2\t+%99%83\t=9\t-1\t+%80\t=1
38
39    Ok(delta)
40}
41
42fn at_destination(delta: &str) -> Result<(), Error> {
43    // initializing the module
44    let dmp = DiffMatchPatch::new();
45
46    // lets recreate the diffs from the minimal `delta` string
47    let delta = dmp.diff_from_delta::<Efficient>(TXT_OLD, delta)?;
48    // Additional step of conveting `delta` -> `patches`
49    let patches = dmp.patch_make(PatchInput::new_diffs(&delta))?;
50
51    // Now, lets apply these patches to the `old_txt` which is the original to get the new text
52    let (new_txt, ops) = dmp.patch_apply(&patches, TXT_OLD)?;
53
54    // Lets print out if the ops succeeded or not
55    ops.iter()
56        .for_each(|&o| println!("{}", if o { "OK" } else { "FAIL" }));
57
58    // If everything goes as per plan you should see
59    // OK
60    // OK
61    // ... and so on
62
63    // lets check out if our `NEW_TXT` (presumably the edited one)
64    if new_txt != TXT_NEW {
65        return Err(Error::InvalidInput);
66    }
67
68    println!("Wallah! Patch applied successfully!");
69
70    Ok(())
71}
72
73fn main() -> Result<(), Error> {
74    // At the source of diff where the old text is being edited we'll create a `delta` - a `delta` is a minimal representation of `diffs`
75    let delta = at_source()?;
76
77    // We'll send this diff to some destination e.g. db or the client where these changes are going to be applied
78
79    // The destination will receive the patch string and will apply the patches to recreate the edits
80    at_destination(&delta)
81}