1pub use vtcode_diff::{
7 Chunk, DiffAlgorithm, DiffBundle, DiffDocument, DiffHunk, DiffLine, DiffLineKind, DiffStats, ParseDiffError,
8 compute_diff_chunks,
9};
10
11#[derive(Debug, Clone)]
13pub struct DiffOptions<'a> {
14 pub context_lines: usize,
15 pub old_label: Option<&'a str>,
16 pub new_label: Option<&'a str>,
17 pub missing_newline_hint: bool,
18}
19
20impl Default for DiffOptions<'_> {
21 fn default() -> Self {
22 Self {
23 context_lines: 3,
24 old_label: None,
25 new_label: None,
26 missing_newline_hint: true,
27 }
28 }
29}
30
31pub fn compute_diff<F>(old: &str, new: &str, options: DiffOptions<'_>, formatter: F) -> DiffBundle
33where
34 F: FnOnce(&[DiffHunk], &DiffOptions<'_>) -> String,
35{
36 let extracted_options = vtcode_diff::DiffOptions {
37 context_lines: options.context_lines,
38 old_label: options.old_label,
39 new_label: options.new_label,
40 missing_newline_hint: options.missing_newline_hint,
41 ..vtcode_diff::DiffOptions::default()
42 };
43
44 vtcode_diff::compute_diff(old, new, extracted_options, |hunks, _| formatter(hunks, &options))
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn legacy_options_struct_literals_remain_supported() {
53 let result = compute_diff(
54 "old\n",
55 "new\n",
56 DiffOptions {
57 context_lines: 0,
58 old_label: None,
59 new_label: None,
60 missing_newline_hint: true,
61 },
62 |hunks, options| {
63 assert_eq!(options.context_lines, 0);
64 hunks.len().to_string()
65 },
66 );
67
68 assert_eq!(result.formatted, "1");
69 }
70}