efficiency/efficiency.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/// NOTE:
7/// This is the `efficiency` mode, here we apply `Diff` and `Patch` operations in `raw bytes &[u8]`.
8/// `Efficiency mode` is called by using `dmp.diff_main::<Efficient>()` or `dmp.patch_from_text::<Efficient>()` APIs
9/// `Efficiency mode` is not compatible with other libraries or implementations of `diff-match-patch`.
10/// Use `efficiency` mode ONLY if you are using this `crate` across your stack
11/// If you want a standardized implementation (working across libraries), use `Compat` mode istead
12///
13///
14// This is the source text
15const TXT_OLD: &str = "I am the very model of a modern Major-General,
16I've information vegetable, animal, and mineral,
17I know the kings of England, and I quote the fights historical,
18From Marathon to Waterloo, in order categorical.
19
20Let'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 đ.";
21
22// Let's assume this to be the text that was editted from the source text
23const TXT_NEW: &str = "I am the very model of a cartoon individual,
24My animation's comical, unusual, and whimsical,
25I'm quite adept at funny gags, comedic theory I have read,
26From wicked puns and stupid jokes to anvils that drop on your head.
27
28Now, 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 đ.";
29
30// An example of a function that creates a diff and returns a set of patches serialized
31fn at_source() -> Result<String, Error> {
32 // initializing the module
33 let dmp = DiffMatchPatch::new();
34
35 // create a list of diffs
36 let diffs = dmp.diff_main::<Efficient>(TXT_OLD, TXT_NEW)?;
37
38 // Now, we are going to create a list of `patches` to be applied to the old text to get the new text
39 let patches = dmp.patch_make(PatchInput::new_diffs(&diffs))?;
40
41 // in the real world you are going to transmit or store this diff serialized to undiff format to be consumed or used somewhere elese
42 let patch_txt = dmp.patch_to_text(&patches);
43
44 // lets see how our patches look
45 println!("{patch_txt:?}");
46 // You should see something like this
47 // @@ -22,225 +22,250 @@\n f a \n-m\n+carto\n o\n-der\n n \n-Major-Ge\n+i\n n\n-er\n+dividu\n al,%0A\n-I've\n+My\n \n-i\n+a\n n\n-for\n+i\n mation\n+'s\n \n-veget\n+comic\n a\n-b\n l\n-e\n , \n-a\n+u\n n\n-im\n+usu\n al, and \n+whi\n m\n+s\n i\n-ner\n+c\n al,%0AI\n+'m\n \n-know \n+qui\n t\n-h\n e \n-kings of Engl\n a\n-n\n d\n-,\n+ept\n a\n+t fu\n n\n-d\n+ny\n \n-I\n+gags,\n \n-qu\n+c\n o\n-t\n+m\n e\n+dic\n the\n+ory\n \n-fights\n+I\n h\n-isto\n+ave \n r\n-ic\n+e\n a\n-l\n+d\n ,%0AFrom \n-M\n+wicked puns \n a\n-ra\n+nd s\n t\n-h\n+upid j\n o\n-n\n+kes\n to \n-W\n+anvils th\n at\n-e\n+ d\n r\n-l\n o\n+p \n o\n-, i\n n \n+y\n o\n-rde\n+u\n r \n-cat\n+h\n e\n-goric\n a\n-l\n+d\n .%0A%0A\n-L\n+Now, l\n et's \n-sta\n+explo\n r\n-t with\n+e\n some \n-bas\n+emot\n i\n-c\n+onal extreme\n s %F0%9F\n-%98\n+%8C\n %8A. W\n@@ -282,55 +282,53 @@\n our \n+ec\n sta\n-ndard sm\n+t\n i\n-ley\n+c\n face %F0%9F\n-%99%82\n+%A4%A9\n , your \n+deva\n s\n+t\n a\n+te\n d face \n-%E2\n+%F0%9F\n %98\n-%B9%EF%B8%8F\n+%AD\n , an\n@@ -338,53 +338,60 @@\n our \n-ang\n+utte\n r\n+l\n y \n+confused \n face %F0%9F\n-%98%A0\n+%A4%AF\n . But \n-w\n+th\n a\n-i\n t\n-, there\n 's \n-m\n+n\n o\n-re\n+t all\n ! %F0%9F%A4\n-%A9\n+%94\n We'\n@@ -411,20 +411,14 @@\n ome \n-more comp\n+subt\n le\n-x\n emo\n@@ -435,78 +435,15 @@\n %F0%9F%98\n-%8D, %F0%9F%A4%A4, and %F0%9F%9A%80. And let's not forget about the classics: %F0%9F%98%89\n+%90\n , %F0%9F\n-%91%8D\n+%99%83\n , an\n@@ -451,6 +451,6 @@\n %F0%9F%91\n-%8F\n+%80\n .\n
48
49 Ok(patch_txt)
50}
51
52fn at_destination(patches: &str) -> Result<(), Error> {
53 // initializing the module
54 let dmp = DiffMatchPatch::new();
55
56 // lets recreate the diffs from patches
57 let patches = dmp.patch_from_text::<Efficient>(patches)?;
58
59 // Now, lets apply these patches to the `old_txt` which is the original to get the new text
60 let (new_txt, ops) = dmp.patch_apply(&patches, TXT_OLD)?;
61
62 // Lets print out if the ops succeeded or not
63 ops.iter()
64 .for_each(|&o| println!("{}", if o { "OK" } else { "FAIL" }));
65
66 // If everything goes as per plan you should see
67 // OK
68 // OK
69 // ... and so on
70
71 // lets check out if our `NEW_TXT` (presumably the edited one)
72 if new_txt != TXT_NEW {
73 return Err(Error::InvalidInput);
74 }
75
76 println!("Wallah! Patch applied successfully!");
77
78 Ok(())
79}
80
81fn main() -> Result<(), Error> {
82 // At the source of diff where the old text is being edited we'll create a set of patches
83 let patches = at_source()?;
84
85 // We'll send this diff to some destination e.g. db or the client where these changes are going to be applied
86
87 // The destination will receive the patch string and will apply the patches to recreate the edits
88 at_destination(&patches)
89}