interdiff_rs/
lib.rs

1//!
2//! The Interdiff library.
3//!
4
5use 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}