Skip to main content

ralph_workflow/git_helpers/repo/
diff_review.rs

1/// The level of truncation applied to a diff for review.
2///
3/// This enum tracks how much a diff has been abbreviated and determines
4/// what instructions should be given to the reviewer agent.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
6pub enum DiffTruncationLevel {
7    /// No truncation - full diff is included
8    #[default]
9    Full,
10    /// Diff was semantically truncated - high-priority files shown, instruction to explore
11    Abbreviated,
12    /// Only file paths listed - instruction to explore each file's diff
13    FileList,
14    /// File list was abbreviated - instruction to explore and discover files
15    FileListAbbreviated,
16}
17
18/// The result of diff truncation for review purposes.
19///
20/// Contains both the potentially-truncated content and metadata about
21/// what truncation was applied, along with version context information.
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct DiffReviewContent {
24    /// The content to include in the review prompt
25    pub content: String,
26    /// The level of truncation applied
27    pub truncation_level: DiffTruncationLevel,
28    /// Total number of files in the full diff (for context in messages)
29    pub total_file_count: usize,
30    /// Number of files shown in the abbreviated content (if applicable)
31    pub shown_file_count: Option<usize>,
32    /// The OID (commit SHA) that this diff is compared against (baseline)
33    pub baseline_oid: Option<String>,
34    /// Short form (first 8 chars) of the baseline OID for display
35    pub baseline_short: Option<String>,
36    /// Description of what the baseline represents (e.g., "`review_baseline`", "`start_commit`")
37    pub baseline_description: String,
38}
39
40impl DiffReviewContent {
41    /// Generate a human-readable header describing the diff's version context.
42    ///
43    /// This header is meant to be included at the beginning of the diff content
44    /// to provide clarity about what state of the code the diff represents.
45    ///
46    /// # Returns
47    ///
48    /// A formatted string like:
49    /// ```text
50    /// Diff Context: Compared against review_baseline abc12345
51    /// Current state: Working directory (includes unstaged changes)
52    /// ```
53    ///
54    /// If no baseline information is available, returns a generic message.
55    #[must_use]
56    pub fn format_context_header(&self) -> String {
57        let mut lines = Vec::new();
58
59        if let Some(short) = &self.baseline_short {
60            lines.push(format!(
61                "Diff Context: Compared against {} {}",
62                self.baseline_description, short
63            ));
64        } else {
65            lines.push("Diff Context: Version information not available".to_string());
66        }
67
68        // Add information about truncation if applicable
69        match self.truncation_level {
70            DiffTruncationLevel::Full => {
71                // No truncation - full diff
72            }
73            DiffTruncationLevel::Abbreviated => {
74                lines.push(format!(
75                    "Note: Diff abbreviated - {}/{} files shown",
76                    self.shown_file_count.unwrap_or(0),
77                    self.total_file_count
78                ));
79            }
80            DiffTruncationLevel::FileList => {
81                lines.push(format!(
82                    "Note: Only file list shown - {} files changed",
83                    self.total_file_count
84                ));
85            }
86            DiffTruncationLevel::FileListAbbreviated => {
87                lines.push(format!(
88                    "Note: File list abbreviated - {}/{} files shown",
89                    self.shown_file_count.unwrap_or(0),
90                    self.total_file_count
91                ));
92            }
93        }
94
95        if lines.is_empty() {
96            String::new()
97        } else {
98            format!("{}\n", lines.join("\n"))
99        }
100    }
101}