use std::fmt::Write;
use std::path::PathBuf;
use chrono::Local;
use num_format::{Locale, ToFormattedString};
use tracing::{info, warn};
use crate::utils::format_file_size;
#[derive(Debug, Default)]
pub struct SyncReport {
pub copied: Vec<PathBuf>, pub errors: Vec<(PathBuf, String)>, pub deleted: Vec<PathBuf>, pub would_delete: Vec<PathBuf>, pub delete_errors: Vec<(PathBuf, String)>, }
pub fn print_report(
is_latest: bool,
report: &SyncReport,
dry_run: bool,
delete_extra: bool,
total_source_files: usize,
total_sync_size: u64,
detail: bool,
) {
if is_latest {
warn!("未发现待同步的文件");
return;
}
let mut output = String::new();
writeln!(
output,
"{}\n源文件总数:{},{}同步文件数: {} ({})",
if dry_run {
"试运行模式"
} else {
"同步成功!"
},
total_source_files.to_formatted_string(&Locale::en),
if dry_run { "待" } else { "" },
report.copied.len().to_formatted_string(&Locale::en),
format_file_size(total_sync_size)
)
.unwrap();
if detail && !report.copied.is_empty() {
writeln!(output, "{}同步的文件:", if dry_run { "待" } else { "" }).unwrap();
for path in &report.copied {
writeln!(output, " - {}", path.display()).unwrap();
}
}
if !dry_run && !report.errors.is_empty() {
writeln!(
output,
"同步错误数: {}",
report.errors.len().to_formatted_string(&Locale::en)
)
.unwrap();
}
if detail && !report.errors.is_empty() {
writeln!(output, "同步错误详情:").unwrap();
for (path, err) in &report.errors {
writeln!(output, " - {}: {}", path.display(), err).unwrap();
}
}
if delete_extra {
let has_delete_data = if dry_run {
!report.would_delete.is_empty() } else {
!report.deleted.is_empty() || !report.delete_errors.is_empty() };
if has_delete_data {
if dry_run {
writeln!(
output,
"待删除文件数: {}",
report.would_delete.len().to_formatted_string(&Locale::en)
)
.unwrap();
if detail && !report.would_delete.is_empty() {
writeln!(output, "待删除的文件:").unwrap();
for path in &report.would_delete {
writeln!(output, " - {}", path.display()).unwrap();
}
}
} else {
writeln!(
output,
"已删除文件数: {}",
report.deleted.len().to_formatted_string(&Locale::en)
)
.unwrap();
if detail && !report.deleted.is_empty() {
writeln!(output, "已删除的文件:").unwrap();
for path in &report.deleted {
writeln!(output, " - {}", path.display()).unwrap();
}
}
if !report.delete_errors.is_empty() {
writeln!(
output,
"删除错误数: {}",
report.delete_errors.len().to_formatted_string(&Locale::en)
)
.unwrap();
if detail {
writeln!(output, "删除错误详情:").unwrap();
for (path, err) in &report.delete_errors {
writeln!(output, " - {}: {}", path.display(), err).unwrap();
}
}
}
}
}
}
let timestamp = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
info!("[{}] {}", timestamp, output);
}