diff --git a/src/tool/fs/helpers.rs b/src/tool/fs/helpers.rs index d766395..9df5d97 100644 --- a/src/tool/fs/helpers.rs +++ b/src/tool/fs/helpers.rs @@ -39,6 +39,22 @@ pub fn not_found_help(ctx: &super::super::ToolCtx, path: &Path, rel: &str) -> St } } +/// Maximum number of lines a diff block may contain before being truncated. +pub const MAX_DIFF_LINES: usize = 200; + +/// Cap a unified diff at `MAX_DIFF_LINES` lines, appending a truncation note. +/// +/// Return: `diff` unchanged if it's within the limit; otherwise the first +/// `MAX_DIFF_LINES` lines followed by `"... ({N} more lines truncated)"`. +pub fn truncate_diff(diff: &str) -> String { + let lines: Vec<&str> = diff.lines().collect(); + if lines.len() <= MAX_DIFF_LINES { + return diff.to_string(); + } + let remaining = lines.len() - MAX_DIFF_LINES; + format!("{}\n... ({remaining} more lines truncated)", lines[..MAX_DIFF_LINES].join("\n")) +} + #[cfg(test)] mod tests { use super::*; @@ -73,4 +89,18 @@ mod tests { let args = json!({"key": null}); assert!(arg_str(&args, "key").is_err()); } + + #[test] + fn test_truncate_diff_under_limit_unchanged() { + let diff = "line1\nline2\nline3"; + assert_eq!(truncate_diff(diff), diff); + } + + #[test] + fn test_truncate_diff_over_limit_truncates() { + let diff = (0..250).map(|i| format!("line{i}")).collect::>().join("\n"); + let result = truncate_diff(&diff); + assert!(result.contains("... (50 more lines truncated)")); + assert_eq!(result.lines().count(), MAX_DIFF_LINES + 1); + } }