java_diff_utils_rs/text/delta_merge/
delta_merge_utils.rs1use crate::patch::chunk::Chunk;
4use crate::patch::delta::Delta;
5use crate::patch::delta_type::DeltaType;
6use crate::text::delta_merge::inline_delta_merge_info::InlineDeltaMergeInfo;
7
8pub struct DeltaMergeUtils;
10
11impl DeltaMergeUtils {
12 pub fn merge_inline_deltas<F>(
15 delta_merge_info: &InlineDeltaMergeInfo<String>,
16 replace_equality: F,
17 ) -> Vec<Delta<String>>
18 where
19 F: Fn(&[String]) -> bool,
20 {
21 let original_deltas = delta_merge_info.deltas();
22 if original_deltas.len() < 2 {
23 return original_deltas.to_vec();
24 }
25
26 let mut new_deltas: Vec<Delta<String>> = Vec::new();
27 new_deltas.push(original_deltas[0].clone());
28
29 for current_delta in original_deltas.iter().skip(1) {
30 let previous_delta = new_deltas.last().unwrap();
31
32 let prev_source_pos = previous_delta.source().position();
33 let prev_source_len = previous_delta.source().len();
34 let start_idx = prev_source_pos + prev_source_len;
35 let end_idx = current_delta.source().position();
36
37 let equalities =
38 if start_idx <= end_idx && end_idx <= delta_merge_info.orig_list().len() {
39 &delta_merge_info.orig_list()[start_idx..end_idx]
40 } else {
41 &[]
42 };
43
44 if replace_equality(equalities) {
45 let mut all_source_lines = Vec::new();
47 all_source_lines.extend(previous_delta.source().lines().iter().cloned());
48 all_source_lines.extend(equalities.iter().cloned());
49 all_source_lines.extend(current_delta.source().lines().iter().cloned());
50
51 let mut all_target_lines = Vec::new();
52 all_target_lines.extend(previous_delta.target().lines().iter().cloned());
53 all_target_lines.extend(equalities.iter().cloned());
54 all_target_lines.extend(current_delta.target().lines().iter().cloned());
55
56 let replacement_source =
57 Chunk::new(previous_delta.source().position(), all_source_lines, None);
58 let replacement_target =
59 Chunk::new(previous_delta.target().position(), all_target_lines, None);
60
61 let replacement =
62 Delta::new(DeltaType::Change, replacement_source, replacement_target);
63
64 new_deltas.pop();
65 new_deltas.push(replacement);
66 } else {
67 new_deltas.push(current_delta.clone());
68 }
69 }
70
71 new_deltas
72 }
73}