| 56 | } |
| 57 | |
| 58 | pub(crate) fn build_hunks_from_diff( |
| 59 | diff_result: &DiffResult, |
| 60 | old_lines: &[&[u8]], |
| 61 | new_lines: &[&[u8]], |
| 62 | context: usize, |
| 63 | ) -> Vec<DiffHunk> { |
| 64 | let mut hunks = Vec::new(); |
| 65 | |
| 66 | // Simple implementation: create one graph_op for all changes |
| 67 | // A more sophisticated implementation would group changes by proximity |
| 68 | |
| 69 | let mut current_hunk: Option<DiffHunk> = None; |
| 70 | let mut old_line = 1; |
| 71 | let mut new_line = 1; |
| 72 | |
| 73 | for op in diff_result.iter() { |
| 74 | match op { |
| 75 | DiffOp::Equal { len, .. } => { |
| 76 | if let Some(ref mut graph_op) = current_hunk { |
| 77 | // Add context lines to current graph_op (up to context limit) |
| 78 | let context_count = cmp::min(*len, context); |
| 79 | for i in 0..context_count { |
| 80 | let content = if new_line - 1 + i < new_lines.len() { |
| 81 | String::from_utf8_lossy(new_lines[new_line - 1 + i]).into_owned() |
| 82 | } else { |
| 83 | String::new() |
| 84 | }; |
| 85 | graph_op.add_line(HunkLine::context(content, old_line + i, new_line + i)); |
| 86 | } |
| 87 | |
| 88 | // If we've shown enough context and there's more equal content, |
| 89 | // close this graph_op |
| 90 | if *len > context * 2 { |
| 91 | graph_op.old_count = graph_op |
| 92 | .lines |
| 93 | .iter() |
| 94 | .filter(|l| l.old_line_num.is_some()) |
| 95 | .count(); |
| 96 | graph_op.new_count = graph_op |
| 97 | .lines |
| 98 | .iter() |
| 99 | .filter(|l| l.new_line_num.is_some()) |
| 100 | .count(); |
| 101 | hunks.push(current_hunk.take().unwrap()); |
| 102 | } |
| 103 | } |
| 104 | old_line += len; |
| 105 | new_line += len; |
| 106 | } |
| 107 | DiffOp::Insert { len, .. } => { |
| 108 | // Start a new graph_op if we don't have one |
| 109 | if current_hunk.is_none() { |
| 110 | let old_start = old_line.saturating_sub(context).max(1); |
| 111 | let new_start = new_line.saturating_sub(context).max(1); |
| 112 | current_hunk = Some(DiffHunk::new(old_start, 0, new_start, 0)); |
| 113 | |
| 114 | // Add leading context |
| 115 | let context_start = new_line.saturating_sub(context); |