Skip to repository content128 lines · 4.0 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T01:57:37.626Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
patch.rs
1#[derive(Debug, Default, Clone)]
2pub struct Patch {
3 pub hunks: Vec<Hunk>,
4}
5
6impl Patch {
7 pub fn parse_unified_diff(unified_diff: &str) -> Patch {
8 let mut current_file = String::new();
9 let mut is_filename_inherited = false;
10 let mut hunk = Hunk::default();
11 let mut patch = Patch::default();
12 let mut in_header = true;
13
14 for line in unified_diff.lines() {
15 if line.starts_with("--- ") || line.starts_with("+++") || line.starts_with("@@") {
16 in_header = false;
17 }
18
19 if in_header {
20 continue;
21 }
22
23 if line.starts_with("@@") {
24 if !hunk.lines.is_empty() {
25 patch.hunks.push(hunk);
26 }
27 hunk = Hunk::from_header(line, ¤t_file, is_filename_inherited);
28 is_filename_inherited = true;
29 } else if let Some(path) = line.strip_prefix("--- ") {
30 is_filename_inherited = false;
31 let path = path.trim().strip_prefix("a/").unwrap_or(path);
32 if path != "/dev/null" {
33 current_file = path.into();
34 }
35 } else if let Some(path) = line.strip_prefix("+++ ") {
36 is_filename_inherited = false;
37 let path = path.trim().strip_prefix("b/").unwrap_or(path);
38 if path != "/dev/null" {
39 current_file = path.into();
40 }
41 } else if let Some(line) = line.strip_prefix('+') {
42 hunk.lines.push(PatchLine::Addition(line.to_string()));
43 } else if let Some(line) = line.strip_prefix('-') {
44 hunk.lines.push(PatchLine::Deletion(line.to_string()));
45 } else if let Some(line) = line.strip_prefix(' ') {
46 hunk.lines.push(PatchLine::Context(line.to_string()));
47 } else {
48 hunk.lines.push(PatchLine::Garbage(line.to_string()));
49 }
50 }
51
52 if !hunk.lines.is_empty() {
53 patch.hunks.push(hunk);
54 }
55
56 patch
57 }
58}
59
60#[derive(Debug, Default, Clone)]
61pub struct Hunk {
62 pub old_start: isize,
63 pub new_start: isize,
64 pub lines: Vec<PatchLine>,
65 pub filename: String,
66}
67
68impl Hunk {
69 pub fn from_header(header: &str, filename: &str, _is_filename_inherited: bool) -> Self {
70 let (old_start, _, new_start, _, _) = Self::parse_hunk_header(header);
71 Self {
72 old_start,
73 new_start,
74 lines: Vec::new(),
75 filename: filename.to_string(),
76 }
77 }
78
79 fn parse_hunk_header(line: &str) -> (isize, isize, isize, isize, String) {
80 let header_part = line.trim_start_matches("@@").trim();
81 let parts: Vec<&str> = header_part.split_whitespace().collect();
82
83 if parts.len() < 2 {
84 return (0, 0, 0, 0, String::new());
85 }
86
87 let old_part = parts[0].trim_start_matches('-');
88 let new_part = parts[1].trim_start_matches('+');
89
90 let (old_start, old_count) = Hunk::parse_hunk_header_range(old_part);
91 let (new_start, new_count) = Hunk::parse_hunk_header_range(new_part);
92
93 let comment = if parts.len() > 2 {
94 parts[2..]
95 .join(" ")
96 .trim_start_matches("@@")
97 .trim()
98 .to_string()
99 } else {
100 String::new()
101 };
102
103 (
104 old_start as isize,
105 old_count as isize,
106 new_start as isize,
107 new_count as isize,
108 comment,
109 )
110 }
111
112 fn parse_hunk_header_range(part: &str) -> (usize, usize) {
113 if let Some((start, count)) = part.split_once(',') {
114 (start.parse().unwrap_or(0), count.parse().unwrap_or(0))
115 } else {
116 (part.parse().unwrap_or(0), 1)
117 }
118 }
119}
120
121#[derive(Clone, Debug, Eq, PartialEq)]
122pub enum PatchLine {
123 Context(String),
124 Addition(String),
125 Deletion(String),
126 Garbage(String),
127}
128