1use crate::cli::table::{MatchDisplayRow, create_match_table};
3use crate::core::matcher::MatchOperation;
4use colored::*;
5use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
6
7pub fn print_success(message: &str) {
9 println!("{} {}", "✓".green().bold(), message);
10}
11
12pub fn print_error(message: &str) {
14 eprintln!("{} {}", "✗".red().bold(), message);
15}
16
17pub fn print_warning(message: &str) {
19 println!("{} {}", "⚠".yellow().bold(), message);
20}
21
22pub fn create_progress_bar(total: u64) -> ProgressBar {
24 let pb = ProgressBar::new(total);
25 if let Ok(cfg) = crate::config::load_config() {
27 if !cfg.general.enable_progress_bar {
28 pb.set_draw_target(ProgressDrawTarget::hidden());
29 }
30 }
31 pb.set_style(
32 ProgressStyle::default_bar()
33 .template(
34 "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta})",
35 )
36 .unwrap(),
37 );
38 pb
39}
40
41pub fn display_ai_usage(usage: &crate::services::ai::AiUsageStats) {
43 println!("🤖 AI API 呼叫詳情:");
44 println!(" 模型: {}", usage.model);
45 println!(" Prompt tokens: {}", usage.prompt_tokens);
46 println!(" Completion tokens: {}", usage.completion_tokens);
47 println!(" Total tokens: {}", usage.total_tokens);
48 println!();
49}
50
51pub fn display_match_results(results: &[MatchOperation], is_dry_run: bool) {
53 if results.is_empty() {
54 println!("{}", "沒有找到匹配的檔案對映".yellow());
55 return;
56 }
57
58 println!("\n{}", "📋 檔案對映結果".bold().blue());
59 if is_dry_run {
60 println!("{}", "🔍 預覽模式 (不會實際修改檔案)".yellow());
61 }
62 println!();
63
64 let rows: Vec<MatchDisplayRow> = results
65 .iter()
66 .enumerate()
67 .map(|(i, op)| {
68 let idx = i + 1;
69 let video = op.video_file.path.to_string_lossy();
70 let subtitle = op.subtitle_file.path.to_string_lossy();
71 let new_name_str = &op.new_subtitle_name;
72 MatchDisplayRow {
73 status: if is_dry_run {
74 "🔍 預覽".yellow().to_string()
75 } else {
76 "✅ 完成".green().to_string()
77 },
78 video_file: format!("影片檔案 {}\n{}", idx, video),
79 subtitle_file: format!("字幕檔案 {}\n{}", idx, subtitle),
80 new_name: format!("新檔名 {}\n{}", idx, new_name_str),
81 }
82 })
83 .collect();
84
85 println!("{}", create_match_table(rows));
86
87 println!(
88 "\n{}",
89 format!("總共處理了 {} 個檔案對映", results.len()).bold()
90 );
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_match_table_display() {
99 let rows = vec![MatchDisplayRow {
100 status: "✅ 完成".to_string(),
101 video_file: "movie1.mp4".to_string(),
102 subtitle_file: "subtitle1.srt".to_string(),
103 new_name: "movie1.srt".to_string(),
104 }];
105
106 let table = create_match_table(rows);
107 assert!(table.contains("movie1.mp4"));
108 }
109}