1use crate::types::{DocDiffFile, DocDiffReport, DocDiffTimelinePoint};
7
8pub fn summarize_file(file: &DocDiffFile) -> DocDiffFile {
10 DocDiffFile {
11 hunks: vec![],
12 blocks: None,
13 ..file.clone()
14 }
15}
16
17pub fn summarize_timeline_point(point: &DocDiffTimelinePoint) -> DocDiffTimelinePoint {
19 DocDiffTimelinePoint {
20 files: point.files.iter().map(summarize_file).collect(),
21 ..point.clone()
22 }
23}
24
25pub fn summarize_report(report: &DocDiffReport) -> DocDiffReport {
27 DocDiffReport {
28 timeline: report
29 .timeline
30 .iter()
31 .map(summarize_timeline_point)
32 .collect(),
33 files: report.files.iter().map(summarize_file).collect(),
34 ..report.clone()
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41 use crate::types::{
42 DocDiffBlock, DocDiffBlockKind, DocDiffFileStatus, DocDiffFileTreeNode, DocDiffHunk,
43 DocDiffLine, DocDiffLineKind, DocDiffTimelinePointKind,
44 };
45
46 fn full_point() -> DocDiffTimelinePoint {
47 DocDiffTimelinePoint {
48 id: "abc123".into(),
49 kind: DocDiffTimelinePointKind::Commit,
50 hash: Some("abc123".into()),
51 short_hash: "abc123".into(),
52 subject: "docs".into(),
53 author: Some("author".into()),
54 date: Some("2026-05-13T00:00:00.000Z".into()),
55 base_ref: "abc122".into(),
56 head_ref: "abc123".into(),
57 files: vec![DocDiffFile {
58 path: "docs/a.md".into(),
59 old_path: None,
60 status: DocDiffFileStatus::Modified,
61 added_lines: 1,
62 removed_lines: 1,
63 hunks: vec![DocDiffHunk {
64 old_start: 1,
65 old_lines: 1,
66 new_start: 1,
67 new_lines: 1,
68 lines: vec![DocDiffLine {
69 kind: DocDiffLineKind::Added,
70 old_line: None,
71 new_line: Some(1),
72 text: "new".into(),
73 }],
74 }],
75 blocks: Some(vec![DocDiffBlock {
76 id: "block".into(),
77 kind: DocDiffBlockKind::Added,
78 raw: "new".into(),
79 html: "<p>new</p>".into(),
80 old_index: None,
81 new_index: Some(1),
82 }]),
83 }],
84 file_tree: vec![DocDiffFileTreeNode::Group {
85 id: "docs".into(),
86 label: "docs".into(),
87 children: vec![DocDiffFileTreeNode::File {
88 id: "docs/a.md".into(),
89 label: "a.md".into(),
90 path: "docs/a.md".into(),
91 old_path: None,
92 status: DocDiffFileStatus::Modified,
93 added_lines: 1,
94 removed_lines: 1,
95 }],
96 }],
97 total_added_lines: 1,
98 total_removed_lines: 1,
99 warnings: vec![],
100 }
101 }
102
103 #[test]
104 fn summarize_strips_hunks_and_blocks() {
105 let summary = summarize_timeline_point(&full_point());
106 assert_eq!(summary.files.len(), 1);
107 assert!(summary.files[0].hunks.is_empty());
108 assert!(summary.files[0].blocks.is_none());
109 assert!(matches!(
110 summary.file_tree[0],
111 DocDiffFileTreeNode::Group { .. }
112 ));
113 }
114}