cargo_plugin_utils/
progress_logger.rs1use std::io::IsTerminal;
4
5use indicatif::{
6 ProgressBar,
7 ProgressStyle,
8};
9
10pub struct ProgressLogger {
15 quiet: bool,
16 progress: Option<ProgressBar>,
17}
18
19impl ProgressLogger {
20 pub fn new(quiet: bool) -> Self {
24 Self {
25 quiet,
26 progress: None,
27 }
28 }
29
30 #[allow(clippy::disallowed_methods)] pub fn should_show_progress(&self) -> bool {
36 if self.quiet {
37 return false;
38 }
39 match std::env::var("CARGO_TERM_PROGRESS_WHEN")
42 .as_deref()
43 .unwrap_or("auto")
44 {
45 "never" => false,
46 "always" => true,
47 "auto" => {
48 std::io::stdout().is_terminal()
50 }
51 _ => {
52 std::io::stdout().is_terminal()
54 }
55 }
56 }
57
58 pub fn set_progress(&mut self, total: u64) {
63 if !self.should_show_progress() {
64 return;
65 }
66 let pb = ProgressBar::new(total);
67 pb.set_style(
69 ProgressStyle::default_bar()
70 .template("{spinner:.green} {msg} [{bar:40.cyan/blue}] {pos}/{len}")
71 .unwrap()
72 .progress_chars("#>-"),
73 );
74 self.progress = Some(pb);
75 }
76
77 pub fn set_message(&self, msg: &str) {
79 if let Some(pb) = &self.progress {
80 pb.set_message(msg.to_string());
81 }
82 }
83
84 pub fn inc(&self) {
86 if let Some(pb) = &self.progress {
87 pb.inc(1);
88 }
89 }
90
91 pub fn println(&mut self, msg: &str) {
95 if !self.quiet {
96 if let Some(pb) = &self.progress {
98 pb.suspend(|| {
99 println!("{}", msg);
100 });
101 } else {
102 println!("{}", msg);
103 }
104 }
105 }
106
107 pub fn status(&mut self, action: &str, target: &str) {
109 if !self.quiet {
110 if let Some(pb) = &self.progress {
111 pb.suspend(|| {
112 println!(" {} {}", action, target);
113 });
114 } else {
115 println!(" {} {}", action, target);
116 }
117 }
118 }
119
120 pub fn finish(&mut self) {
122 if let Some(pb) = self.progress.take() {
123 pb.finish_and_clear();
124 }
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn test_progress_logger_new() {
134 let logger = ProgressLogger::new(false);
135 assert!(!logger.quiet);
136 assert!(logger.progress.is_none());
137 }
138
139 #[test]
140 fn test_progress_logger_quiet() {
141 let logger = ProgressLogger::new(true);
142 assert!(logger.quiet);
143 assert!(!logger.should_show_progress());
144 }
145
146 #[test]
147 fn test_progress_logger_set_progress() {
148 let mut logger = ProgressLogger::new(false);
149 logger.set_progress(10);
150 }
154
155 #[test]
156 fn test_progress_logger_inc() {
157 let mut logger = ProgressLogger::new(false);
158 logger.set_progress(10);
159 logger.inc();
160 }
162
163 #[test]
164 fn test_progress_logger_finish() {
165 let mut logger = ProgressLogger::new(false);
166 logger.set_progress(10);
167 logger.finish();
168 assert!(logger.progress.is_none());
169 }
170}