mago_feedback/
progress.rs1#![allow(unknown_lints)]
2#![allow(clippy::literal_string_with_formatting_args)]
3
4use std::sync::LazyLock;
5
6use indicatif::MultiProgress;
7use indicatif::ProgressBar;
8use indicatif::ProgressStyle;
9
10pub static GLOBAL_PROGRESS_MANAGER: LazyLock<MultiProgress> = LazyLock::new(MultiProgress::new);
12
13pub fn create_progress_bar(length: usize, prefix: &'static str, theme: ProgressBarTheme) -> ProgressBar {
24 let pb = GLOBAL_PROGRESS_MANAGER.add(ProgressBar::new(length as u64));
25 pb.set_style(
26 ProgressStyle::with_template(theme.template())
27 .unwrap()
28 .progress_chars(theme.progress_chars())
29 .tick_chars(theme.tick_chars()),
30 );
31
32 pb.set_prefix(prefix);
33
34 pb
35}
36
37pub fn remove_progress_bar(progress_bar: ProgressBar) {
43 progress_bar.finish_and_clear();
44
45 GLOBAL_PROGRESS_MANAGER.remove(&progress_bar);
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
50pub enum ProgressBarTheme {
51 Red,
52 Yellow,
53 Green,
54 Blue,
55 Magenta,
56 Cyan,
57}
58
59impl ProgressBarTheme {
60 pub fn template(&self) -> &'static str {
62 match self {
63 Self::Red => "{spinner} {prefix:<16.bold}▕{wide_bar:.red}▏{pos:>6}/{len}▕ {percent:>3}%▕ ETA: {eta_precise}▕ Elapsed: {elapsed_precise}",
64 Self::Yellow => "{spinner} {prefix:<16.bold}▕{wide_bar:.yellow}▏{pos:>6}/{len}▕ {percent:>3}%▕ ETA: {eta_precise}▕ Elapsed: {elapsed_precise}",
65 Self::Green => "{spinner} {prefix:<16.bold}▕{wide_bar:.green}▏{pos:>6}/{len}▕ {percent:>3}%▕ ETA: {eta_precise}▕ Elapsed: {elapsed_precise}",
66 Self::Blue => "{spinner} {prefix:<16.bold}▕{wide_bar:.blue}▏{pos:>6}/{len}▕ {percent:>3}%▕ ETA: {eta_precise}▕ Elapsed: {elapsed_precise}",
67 Self::Magenta => "{spinner} {prefix:<16.bold}▕{wide_bar:.magenta}▏{pos:>6}/{len}▕ {percent:>3}%▕ ETA: {eta_precise}▕ Elapsed: {elapsed_precise}",
68 Self::Cyan => "{spinner} {prefix:<16.bold}▕{wide_bar:.cyan}▏{pos:>6}/{len}▕ {percent:>3}%▕ ETA: {eta_precise}▕ Elapsed: {elapsed_precise}",
69 }
70 }
71
72 pub fn progress_chars(&self) -> &'static str {
74 match self {
75 ProgressBarTheme::Red => "█░ ",
76 ProgressBarTheme::Yellow => "█▉▊▋▌▍▎▏░ ",
77 ProgressBarTheme::Green => "█▇▆▅▄▃▂▁░ ",
78 ProgressBarTheme::Blue => "█▓▒░░ ",
79 ProgressBarTheme::Magenta => "█▛▌▖░ ",
80 ProgressBarTheme::Cyan => "█▉▊▋▌▍▎▏░ ",
81 }
82 }
83
84 pub fn tick_chars(&self) -> &'static str {
86 match self {
87 ProgressBarTheme::Red => "⠁⠂⠄⡀⢀⠠⠐⠈ ",
88 ProgressBarTheme::Yellow => "⢀⠠⠐⠈⠁⠂⠄⡀ ",
89 ProgressBarTheme::Green => "⠄⡀⢀⠠⠐⠈⠁⠂ ",
90 ProgressBarTheme::Blue => "⡀⢀⠠⠐⠈⠁⠂⠄ ",
91 ProgressBarTheme::Magenta => "⠐⠈⠁⠂⠄⡀⢀⠠ ",
92 ProgressBarTheme::Cyan => "⠠⠐⠈⠁⠂⠄⡀⢀ ",
93 }
94 }
95}