Skip to main content

branchdiff/diff/
line_builder.rs

1//! Line construction helpers for DiffLine.
2//!
3//! These associated functions create specific types of diff lines:
4//! file headers, image markers, elided sections, etc.
5
6use super::{DiffLine, LineSource};
7
8impl DiffLine {
9    /// Create a file header line for a new or modified file.
10    pub fn file_header(path: &str) -> Self {
11        Self {
12            source: LineSource::FileHeader,
13            content: path.to_string(),
14            prefix: ' ',
15            line_number: None,
16            file_path: Some(path.to_string()),
17            inline_spans: Vec::new(),
18            old_content: None,
19            change_source: None,
20        }
21    }
22
23    /// Create a file header line for a deleted file.
24    pub fn deleted_file_header(path: &str) -> Self {
25        Self {
26            source: LineSource::FileHeader,
27            content: format!("{} (deleted)", path),
28            prefix: ' ',
29            line_number: None,
30            file_path: Some(path.to_string()),
31            inline_spans: Vec::new(),
32            old_content: None,
33            change_source: None,
34        }
35    }
36
37    /// Create a file header line for a renamed file.
38    pub fn renamed_file_header(old_path: &str, new_path: &str) -> Self {
39        Self {
40            source: LineSource::FileHeader,
41            content: format!("{} → {}", old_path, new_path),
42            prefix: ' ',
43            line_number: None,
44            file_path: Some(new_path.to_string()),
45            inline_spans: Vec::new(),
46            old_content: None,
47            change_source: None,
48        }
49    }
50
51    /// Create an image marker line (UI layer will render actual image).
52    pub fn image_marker(path: &str) -> Self {
53        Self {
54            source: LineSource::Base,
55            content: "[image]".to_string(),
56            prefix: ' ',
57            line_number: None,
58            file_path: Some(path.to_string()),
59            inline_spans: Vec::new(),
60            old_content: None,
61            change_source: None,
62        }
63    }
64
65    /// Create an elided lines marker (shows count of hidden lines).
66    pub fn elided(count: usize) -> Self {
67        Self {
68            source: LineSource::Elided,
69            content: format!("{} lines", count),
70            prefix: ' ',
71            line_number: None,
72            file_path: None,
73            inline_spans: Vec::new(),
74            old_content: None,
75            change_source: None,
76        }
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_file_header() {
86        let header = DiffLine::file_header("src/main.rs");
87        assert_eq!(header.source, LineSource::FileHeader);
88        assert_eq!(header.content, "src/main.rs");
89        assert_eq!(header.file_path, Some("src/main.rs".to_string()));
90    }
91
92    #[test]
93    fn test_deleted_file_header() {
94        let header = DiffLine::deleted_file_header("old/file.rs");
95        assert_eq!(header.source, LineSource::FileHeader);
96        assert_eq!(header.content, "old/file.rs (deleted)");
97        assert_eq!(header.file_path, Some("old/file.rs".to_string()));
98    }
99
100    #[test]
101    fn test_renamed_file_header() {
102        let header = DiffLine::renamed_file_header("old/path.rs", "new/path.rs");
103        assert_eq!(header.source, LineSource::FileHeader);
104        assert_eq!(header.content, "old/path.rs → new/path.rs");
105        assert_eq!(header.file_path, Some("new/path.rs".to_string()));
106    }
107
108    #[test]
109    fn test_image_marker() {
110        let marker = DiffLine::image_marker("image.png");
111        assert_eq!(marker.source, LineSource::Base);
112        assert_eq!(marker.content, "[image]");
113        assert!(marker.is_image_marker());
114    }
115
116    #[test]
117    fn test_elided() {
118        let elided = DiffLine::elided(42);
119        assert_eq!(elided.source, LineSource::Elided);
120        assert_eq!(elided.content, "42 lines");
121        assert_eq!(elided.file_path, None);
122    }
123}