1use colored::Colorize;
2use indicatif::{ProgressBar, ProgressStyle};
3use std::sync::Arc;
4
5pub struct ProgressReporter {
6 verbose: bool,
7 spinner: Option<Arc<ProgressBar>>,
8}
9
10impl ProgressReporter {
11 pub fn new(verbose: bool) -> Self {
12 Self {
13 verbose,
14 spinner: None,
15 }
16 }
17
18 pub fn start_spinner(&mut self, message: &str) {
19 if !self.verbose {
20 let pb = ProgressBar::new_spinner();
21 pb.set_style(
22 ProgressStyle::default_spinner()
23 .template("{spinner:.cyan} {msg}")
24 .unwrap(),
25 );
26 pb.set_message(message.to_string());
27 pb.enable_steady_tick(std::time::Duration::from_millis(100));
28 self.spinner = Some(Arc::new(pb));
29 } else {
30 println!("{}", format!("⏳ {}", message).bright_cyan());
31 }
32 }
33
34 pub fn finish_spinner(&mut self, message: &str) {
35 if let Some(spinner) = self.spinner.take() {
36 spinner.finish_with_message(message.to_string());
37 } else if self.verbose {
38 println!("{}", format!("✅ {}", message).green());
39 }
40 }
41
42 pub fn info(&self, message: &str) {
43 if self.verbose {
44 println!("{}", format!("ℹ️ {}", message).bright_blue());
45 }
46 }
47
48 pub fn success(&self, message: &str) {
49 println!("{}", format!("✅ {}", message).green());
50 }
51
52 pub fn warning(&self, message: &str) {
53 println!("{}", format!("⚠️ {}", message).yellow());
54 }
55
56 pub fn error(&self, message: &str) {
57 eprintln!("{}", format!("❌ {}", message).red());
58 }
59}
60
61impl Drop for ProgressReporter {
62 fn drop(&mut self) {
63 if let Some(spinner) = self.spinner.take() {
64 spinner.finish_and_clear();
65 }
66 }
67}