1use similar::TextDiff;
2
3pub fn format_unified_diff(original: &str, modified: &str, label_a: &str, label_b: &str) -> String {
4 let diff = TextDiff::from_lines(original, modified);
5 let mut output = String::new();
6
7 output.push_str(&format!("--- {}\n", label_a));
8 output.push_str(&format!("+++ {}\n", label_b));
9
10 for hunk in diff.unified_diff().context_radius(3).iter_hunks() {
11 output.push_str(&format!("{}", hunk));
12 }
13
14 output
15}
16
17#[cfg(test)]
18mod tests {
19 use super::*;
20
21 #[test]
22 fn format_diff_shows_unified_output() {
23 let original = "line1\nline2\nline3\n";
24 let modified = "line1\nmodified_line2\nline3\nnew_line4\n";
25 let output = format_unified_diff(
26 original,
27 modified,
28 "deployed: .config/app.conf",
29 "current: .config/app.conf",
30 );
31 assert!(output.contains("--- deployed:"));
32 assert!(output.contains("+++ current:"));
33 assert!(output.contains("-line2"));
34 assert!(output.contains("+modified_line2"));
35 assert!(output.contains("+new_line4"));
36 }
37
38 #[test]
39 fn no_diff_produces_empty_output() {
40 let content = "same\ncontent\n";
41 let output = format_unified_diff(content, content, "a", "b");
42 assert!(output.starts_with("--- a\n+++ b\n"));
44 assert!(!output.contains("@@"));
46 }
47}