1use std::collections::VecDeque;
6
7use log::*;
8
9use patch_rs::Patch;
10
11pub fn interdiff(mut patch_1: Patch, mut patch_2: Patch, context_radius: usize) -> Patch {
12 let mut interdiff = Patch {
13 input: patch_1.output.to_owned(),
14 output: patch_2.output.to_owned(),
15 contexts: VecDeque::new(),
16 };
17 let mut patch_1_offset = 0;
18 let mut patch_2_offset = 0;
19
20 trace!("DRAINING BOTH PATCHES");
21 while !patch_1.contexts.is_empty() && !patch_2.contexts.is_empty() {
22 let p1 = patch_1.contexts.front().unwrap();
23 let p2 = patch_2.contexts.front().unwrap();
24 if p1.header.file1_l <= p2.header.file1_l {
25 let context = patch_1.contexts.pop_front().unwrap();
26 let flipped = context.flip(context_radius);
27 for mut context in flipped.into_iter() {
28 context.shift(patch_2_offset);
29 patch_1_offset += context.offset();
30 interdiff.contexts.push_back(context);
31 }
32 } else {
33 let context = patch_2.contexts.pop_front().unwrap();
34 let reduced = context.reduce(context_radius);
35 for mut context in reduced.into_iter() {
36 context.shift(-patch_1_offset);
37 patch_2_offset += context.offset();
38 interdiff.contexts.push_back(context);
39 }
40 }
41 }
42 trace!("DRAINING FIRST PATCH");
43 while !patch_1.contexts.is_empty() {
44 let context = patch_1.contexts.pop_front().unwrap();
45 let flipped = context.flip(context_radius);
46 for mut context in flipped.into_iter() {
47 context.shift(patch_2_offset);
48 patch_1_offset += context.offset();
49 interdiff.contexts.push_back(context);
50 }
51 }
52 trace!("DRAINING SECOND PATCH");
53 while !patch_2.contexts.is_empty() {
54 let context = patch_2.contexts.pop_front().unwrap();
55 let reduced = context.reduce(context_radius);
56 for mut context in reduced.into_iter() {
57 context.shift(-patch_1_offset);
58 patch_2_offset += context.offset();
59 interdiff.contexts.push_back(context);
60 }
61 }
62
63 interdiff
64}