#[derive(Debug, Clone)]
pub struct WorkerTask {
pub id: String,
pub target: String,
pub instruction: String,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct Hunk {
pub start_line: usize,
pub end_line: usize,
pub content: String,
pub worker_id: String,
}
impl Hunk {
#[allow(dead_code)]
pub fn sort_key(&self) -> (std::cmp::Reverse<usize>, std::cmp::Reverse<usize>) {
(
std::cmp::Reverse(self.start_line),
std::cmp::Reverse(self.end_line),
)
}
}
pub fn parse_master_spec(xml_content: &str) -> Vec<WorkerTask> {
let mut tasks = Vec::new();
let iter = xml_content.split("<worker_task");
for block in iter.skip(1) {
let Some(tag_end) = block.find('>') else {
continue;
};
let tag_attrs = &block[..tag_end];
let id_start = tag_attrs.find("id=\"").map(|i| i + 4).unwrap_or(0);
let id_end = tag_attrs[id_start..].find('"').unwrap_or(0) + id_start;
let id = &tag_attrs[id_start..id_end];
let target_start = tag_attrs.find("target=\"").map(|i| i + 8).unwrap_or(0);
let target_end = tag_attrs[target_start..].find('"').unwrap_or(0) + target_start;
let target = &tag_attrs[target_start..target_end];
let content_block = &block[tag_end + 1..];
let Some(content_end) = content_block.find("</worker_task>") else {
continue;
};
let instruction = content_block[..content_end].trim();
tasks.push(WorkerTask {
id: id.to_string(),
target: target.to_string(),
instruction: instruction.to_string(),
});
}
tasks
}
#[allow(dead_code)]
pub fn parse_scratchpad_diffs(raw_content: &str, worker_id: String) -> Vec<Hunk> {
let mut hunks = Vec::new();
let mut current_pos = 0;
fn parse_attr(attr_str: &str, key: &str) -> Option<usize> {
let key_match = format!("{}=\"", key);
let start = attr_str.find(&key_match)? + key_match.len();
let end = attr_str[start..].find('"')? + start;
attr_str[start..end].parse().ok()
}
while let Some(start_idx) = raw_content[current_pos..].find("<patch") {
let absolute_start = current_pos + start_idx;
let Some(tag_end) = raw_content[absolute_start..].find('>') else {
break;
};
let attr_str = &raw_content[absolute_start..absolute_start + tag_end];
let start_line = parse_attr(attr_str, "start").unwrap_or(0);
let end_line = parse_attr(attr_str, "end").unwrap_or(0);
let body_start = absolute_start + tag_end + 1;
if let Some(end_idx) = raw_content[body_start..].find("</patch>") {
let content = raw_content[body_start..body_start + end_idx]
.trim()
.to_string();
hunks.push(Hunk {
start_line,
end_line,
content,
worker_id: worker_id.clone(),
});
current_pos = body_start + end_idx + 8;
} else {
break;
}
}
hunks
}