morph_cli/core/diff/
report.rs1use std::path::PathBuf;
2use std::time::Instant;
3
4use super::preview::{ChangedFile, SkipReason, SkippedFile, TransformationReport};
5
6#[derive(Debug, Clone, Default)]
7#[allow(dead_code)]
8pub struct AggregatedStats {
9 pub total_files: usize,
10 pub changed_files: usize,
11 pub skipped_files: usize,
12 pub lines_added: usize,
13 pub lines_removed: usize,
14 pub execution_time_ms: u64,
15 pub patterns_detected: usize,
16}
17
18impl AggregatedStats {
19 #[allow(dead_code)]
20 pub fn new() -> Self {
21 Self::default()
22 }
23
24 #[allow(dead_code)]
25 pub fn add_changed_file(&mut self, file: &ChangedFile) {
26 self.changed_files += 1;
27 self.lines_added += file.lines_added;
28 self.lines_removed += file.lines_removed;
29 }
30
31 #[allow(dead_code)]
32 pub fn add_skipped_file(&mut self) {
33 self.skipped_files += 1;
34 }
35
36 #[allow(dead_code)]
37 pub fn finalize(&mut self, execution_time_ms: u64) {
38 self.execution_time_ms = execution_time_ms;
39 self.total_files = self.changed_files + self.skipped_files;
40 }
41}
42
43impl From<&TransformationReport> for AggregatedStats {
44 fn from(report: &TransformationReport) -> Self {
45 let mut stats = AggregatedStats::new();
46 stats.changed_files = report.total_changed();
47 stats.skipped_files = report.total_files_skipped();
48 stats.lines_added = report.total_lines_added();
49 stats.lines_removed = report.total_lines_removed();
50 stats.execution_time_ms = report.execution_time_ms;
51 stats.total_files = stats.changed_files + stats.skipped_files;
52 stats
53 }
54}
55
56#[derive(Debug, Clone)]
57#[allow(dead_code)]
58pub struct ExecutionTimer {
59 start: Instant,
60}
61
62impl ExecutionTimer {
63 #[allow(dead_code)]
64 pub fn new() -> Self {
65 Self {
66 start: Instant::now(),
67 }
68 }
69
70 #[allow(dead_code)]
71 pub fn elapsed_ms(&self) -> u64 {
72 self.start.elapsed().as_millis() as u64
73 }
74}
75
76impl Default for ExecutionTimer {
77 fn default() -> Self {
78 Self::new()
79 }
80}
81
82pub struct ReportBuilder {
83 #[allow(dead_code)]
84 report: TransformationReport,
85}
86
87impl ReportBuilder {
88 #[allow(dead_code)]
89 pub fn new() -> Self {
90 Self {
91 report: TransformationReport::new(),
92 }
93 }
94
95 #[allow(dead_code)]
96 pub fn add_changed(&mut self, path: PathBuf, lines_added: usize, lines_removed: usize) {
97 self.report.changed_files.push(ChangedFile {
98 path,
99 lines_added,
100 lines_removed,
101 preview: None,
102 });
103 }
104
105 #[allow(dead_code)]
106 pub fn add_skipped(&mut self, path: PathBuf, reason: SkipReason) {
107 self.report.skipped_files.push(SkippedFile { path, reason });
108 }
109
110 #[allow(dead_code)]
111 pub fn build(mut self) -> TransformationReport {
112 self.report.finish();
113 self.report
114 }
115}
116
117impl Default for ReportBuilder {
118 fn default() -> Self {
119 Self::new()
120 }
121}