ccsync_core/sync/
reporting.rs

1//! Sync operation reporting and statistics
2
3use std::fmt::Write;
4
5use super::SyncResult;
6
7/// Sync operation reporter
8pub struct SyncReporter;
9
10impl SyncReporter {
11    /// Generate a summary report
12    #[must_use]
13    pub fn generate_summary(result: &SyncResult) -> String {
14        let mut output = String::new();
15
16        output.push_str("\n=== Sync Summary ===\n");
17        let _ = writeln!(output, "Created:  {}", result.created);
18        let _ = writeln!(output, "Updated:  {}", result.updated);
19        let _ = writeln!(output, "Deleted:  {}", result.deleted);
20
21        // Show skipped count with reasons breakdown
22        if result.skipped > 0 && !result.skip_reasons.is_empty() {
23            let _ = write!(output, "Skipped:  {}", result.skipped);
24            let mut reasons: Vec<_> = result.skip_reasons.iter().collect();
25            reasons.sort_by_key(|(_, count)| std::cmp::Reverse(**count));
26            for (reason, count) in reasons {
27                let _ = write!(output, " ({reason}: {count})");
28            }
29            let _ = writeln!(output);
30        } else {
31            let _ = writeln!(output, "Skipped:  {}", result.skipped);
32        }
33
34        let _ = writeln!(output, "Conflicts: {}", result.conflicts);
35
36        if !result.errors.is_empty() {
37            let _ = writeln!(output, "\nErrors ({}):", result.errors.len());
38            for error in &result.errors {
39                let _ = writeln!(output, "  - {error}");
40            }
41        }
42
43        let _ = writeln!(output, "\nTotal operations: {}", result.total_operations());
44
45        if result.is_success() {
46            output.push_str("Status: ✓ Success\n");
47        } else {
48            output.push_str("Status: ✗ Completed with errors\n");
49        }
50
51        output
52    }
53}