aico/diffing/
diff_utils.rs1use similar::TextDiff;
2use std::borrow::Cow;
3
4pub fn generate_diff(
5 filename: &str,
6 old_content: Option<&str>,
7 new_content: Option<&str>,
8) -> String {
9 let from_header = if old_content.is_none() {
10 "/dev/null".to_string()
11 } else {
12 format!("a/{}", filename)
13 };
14
15 let to_header = if new_content.is_none()
16 || (new_content == Some("") && !old_content.unwrap_or("").is_empty())
17 {
18 "/dev/null".to_string()
19 } else {
20 format!("b/{}", filename)
21 };
22
23 let old_text = old_content.unwrap_or("");
24 let new_text = new_content.unwrap_or("");
25
26 let diff = TextDiff::from_lines(old_text, new_text)
27 .unified_diff()
28 .header("e_filename(&from_header), "e_filename(&to_header))
29 .missing_newline_hint(true)
30 .to_string();
31
32 if diff.is_empty() && old_content.is_none() != new_content.is_none() {
35 return format!(
36 "--- {}\n+++ {}\n",
37 quote_filename(&from_header),
38 quote_filename(&to_header)
39 );
40 }
41
42 diff
43}
44
45fn quote_filename(filename: &str) -> Cow<'_, str> {
46 if filename.contains(' ') {
47 format!("\"{}\"", filename).into()
48 } else {
49 filename.into()
50 }
51}