Skip to main content

gn_core/
diff.rs

1use crate::note::Note;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct HunkAnchor {
5    pub file: String,
6    pub line_start: u32,
7    pub line_end: u32,
8    pub commit: String,
9}
10
11impl HunkAnchor {
12    pub fn matches_note(&self, note: &Note) -> bool {
13        if note.commit != self.commit {
14            return false;
15        }
16        if let Some(ref f) = note.file {
17            if f != &self.file {
18                return false;
19            }
20        }
21        if let (Some(ns), Some(ne)) = (note.line_start, note.line_end) {
22            // Checks if the hunk overlaps with the note
23            if ne < self.line_start || ns > self.line_end {
24                return false;
25            }
26        }
27        true
28    }
29}
30
31pub fn parse_diff_hunks(patch: &str) -> Vec<HunkAnchor> {
32    let mut anchors = Vec::new();
33    let mut current_file = String::new();
34    let current_commit = "pending".to_string(); // In a real setup, this would be parsed or passed in
35
36    for line in patch.lines() {
37        if let Some(f) = line.strip_prefix("+++ b/") {
38            current_file = f.to_string();
39        } else if line.starts_with("@@ ") {
40            // Parse @@ -a,b +c,d @@
41            if let Some(end_idx) = line[3..].find(" @@") {
42                let hunk_info = &line[3..3 + end_idx];
43                let parts: Vec<&str> = hunk_info.split_whitespace().collect();
44                if parts.len() >= 2 {
45                    let added = parts[1]; // e.g. +c,d
46                    let added_nums = &added[1..];
47                    let line_parts: Vec<&str> = added_nums.split(',').collect();
48                    if !line_parts.is_empty() {
49                        if let Ok(start) = line_parts[0].parse::<u32>() {
50                            let count = if line_parts.len() > 1 {
51                                line_parts[1].parse::<u32>().unwrap_or(1)
52                            } else {
53                                1
54                            };
55                            anchors.push(HunkAnchor {
56                                file: current_file.clone(),
57                                line_start: start,
58                                line_end: start + count.saturating_sub(1),
59                                commit: current_commit.clone(),
60                            });
61                        }
62                    }
63                }
64            }
65        }
66    }
67
68    anchors
69}