pub fn edit_trailer(added: usize, removed: usize) -> String {
format!("[+{added} -{removed}]")
}
pub fn parse_edit_trailers(content: &str) -> Option<(u64, u64)> {
let mut found = false;
let mut added = 0u64;
let mut removed = 0u64;
for line in content.lines() {
let Some((plus, minus)) = parse_one(line.trim_end()) else {
continue;
};
found = true;
added += plus;
removed += minus;
}
found.then_some((added, removed))
}
fn parse_one(line: &str) -> Option<(u64, u64)> {
let inner = line.strip_prefix("[+")?.strip_suffix(']')?;
let (plus, minus) = inner.split_once(" -")?;
Some((plus.parse().ok()?, minus.parse().ok()?))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn trailer_round_trips_and_sums() {
assert_eq!(edit_trailer(12, 3), "[+12 -3]");
assert_eq!(parse_edit_trailers("Wrote a.rs\n\n[+12 -3]"), Some((12, 3)));
assert_eq!(
parse_edit_trailers(
"Patch applied to `a` (1 hunk).\n[+1 -1]\nPatch applied to `b` (2 hunks).\n[+4 -0]\n"
),
Some((5, 1))
);
assert_eq!(parse_edit_trailers("Edited a.rs"), None);
assert_eq!(parse_edit_trailers("[+x -1]"), None);
assert_eq!(parse_edit_trailers("[+1 -]"), None);
assert_eq!(parse_edit_trailers("[+1]"), None);
assert_eq!(parse_edit_trailers("+1 -2]"), None);
}
}