Skip to main content

ta_changeset/
diff.rs

1// diff.rs — Diff content representations.
2//
3// A DiffContent describes what changed. It can be a text diff, a new file,
4// a deleted file, or a summary for binary files (images, PDFs, etc.).
5//
6// This is the "what" — the ChangeSet wraps it with the "where" and "why".
7
8use serde::{Deserialize, Serialize};
9
10/// The actual content of a change.
11///
12/// Rust enums can carry different data per variant — this is called a
13/// "tagged union" or "sum type". In JSON, serde uses a "type" tag to
14/// distinguish variants.
15#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
16#[serde(tag = "type", rename_all = "snake_case")]
17pub enum DiffContent {
18    /// A standard unified diff (like `git diff` output).
19    UnifiedDiff {
20        /// The diff text in unified format.
21        content: String,
22    },
23
24    /// A brand new file is being created.
25    CreateFile {
26        /// The full file content as UTF-8 text.
27        /// For binary files, use BinarySummary instead.
28        content: String,
29    },
30
31    /// A file is being deleted entirely.
32    DeleteFile,
33
34    /// Summary for a binary file (no text diff possible).
35    BinarySummary {
36        /// MIME type (e.g., "image/png", "application/pdf").
37        mime_type: String,
38        /// File size in bytes.
39        size_bytes: u64,
40        /// SHA-256 hash of the binary content.
41        hash: String,
42    },
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn unified_diff_serialization_round_trip() {
51        let diff = DiffContent::UnifiedDiff {
52            content: "--- a/file.txt\n+++ b/file.txt\n@@ -1 +1 @@\n-old\n+new".to_string(),
53        };
54        let json = serde_json::to_string(&diff).unwrap();
55        let restored: DiffContent = serde_json::from_str(&json).unwrap();
56        assert_eq!(diff, restored);
57    }
58
59    #[test]
60    fn create_file_serialization() {
61        let diff = DiffContent::CreateFile {
62            content: "fn main() {}".to_string(),
63        };
64        let json = serde_json::to_string(&diff).unwrap();
65        assert!(json.contains("\"create_file\""));
66    }
67
68    #[test]
69    fn binary_summary_serialization() {
70        let diff = DiffContent::BinarySummary {
71            mime_type: "image/png".to_string(),
72            size_bytes: 1024,
73            hash: "abc123".to_string(),
74        };
75        let json = serde_json::to_string(&diff).unwrap();
76        let restored: DiffContent = serde_json::from_str(&json).unwrap();
77        assert_eq!(diff, restored);
78    }
79}