whycodes_core/
edit_trailer.rs1pub fn edit_trailer(added: usize, removed: usize) -> String {
10 format!("[+{added} -{removed}]")
11}
12
13pub fn parse_edit_trailers(content: &str) -> Option<(u64, u64)> {
16 let mut found = false;
17 let mut added = 0u64;
18 let mut removed = 0u64;
19 for line in content.lines() {
20 let Some((plus, minus)) = parse_one(line.trim_end()) else {
21 continue;
22 };
23 found = true;
24 added += plus;
25 removed += minus;
26 }
27 found.then_some((added, removed))
28}
29
30fn parse_one(line: &str) -> Option<(u64, u64)> {
31 let inner = line.strip_prefix("[+")?.strip_suffix(']')?;
32 let (plus, minus) = inner.split_once(" -")?;
33 Some((plus.parse().ok()?, minus.parse().ok()?))
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn trailer_round_trips_and_sums() {
42 assert_eq!(edit_trailer(12, 3), "[+12 -3]");
43 assert_eq!(parse_edit_trailers("Wrote a.rs\n\n[+12 -3]"), Some((12, 3)));
44 assert_eq!(
45 parse_edit_trailers(
46 "Patch applied to `a` (1 hunk).\n[+1 -1]\nPatch applied to `b` (2 hunks).\n[+4 -0]\n"
47 ),
48 Some((5, 1))
49 );
50 assert_eq!(parse_edit_trailers("Edited a.rs"), None);
51 assert_eq!(parse_edit_trailers("[+x -1]"), None);
52 assert_eq!(parse_edit_trailers("[+1 -]"), None);
53 assert_eq!(parse_edit_trailers("[+1]"), None);
54 assert_eq!(parse_edit_trailers("+1 -2]"), None);
55 }
56}