1
+ //! Support for CLI progress bars.
2
+
1
3
use std:: cmp;
2
4
use std:: time:: { Duration , Instant } ;
3
5
@@ -7,13 +9,49 @@ use crate::util::{CargoResult, Config};
7
9
use cargo_util:: is_ci;
8
10
use unicode_width:: UnicodeWidthChar ;
9
11
12
+ /// CLI progress bar.
13
+ ///
14
+ /// The `Progress` object can be in an enabled or disabled state. When
15
+ /// disabled, calling any of the methods to update it will not display
16
+ /// anything. Disabling is typically done by the user with options such as
17
+ /// `--quiet` or the `term.progress` config option.
18
+ ///
19
+ /// There are several methods to update the progress bar and to cause it to
20
+ /// update its display.
21
+ ///
22
+ /// The bar will be removed from the display when the `Progress` object is
23
+ /// dropped or [`Progress::clear`] is called.
24
+ ///
25
+ /// The progress bar has built-in rate limiting to avoid updating the display
26
+ /// too fast. It should usually be fine to call [`Progress::tick`] as often as
27
+ /// needed, though be cautious if the tick rate is very high or it is
28
+ /// expensive to compute the progress value.
10
29
pub struct Progress < ' cfg > {
11
30
state : Option < State < ' cfg > > ,
12
31
}
13
32
33
+ /// Indicates the style of information for displaying the amount of progress.
34
+ ///
35
+ /// See also [`Progress::print_now`] for displaying progress without a bar.
14
36
pub enum ProgressStyle {
37
+ /// Displays progress as a percentage.
38
+ ///
39
+ /// Example: `Fetch [=====================> ] 88.15%`
40
+ ///
41
+ /// This is good for large values like number of bytes downloaded.
15
42
Percentage ,
43
+ /// Displays progress as a ratio.
44
+ ///
45
+ /// Example: `Building [===> ] 35/222`
46
+ ///
47
+ /// This is good for smaller values where the exact number is useful to see.
16
48
Ratio ,
49
+ /// Does not display an exact value of how far along it is.
50
+ ///
51
+ /// Example: `Fetch [===========> ]`
52
+ ///
53
+ /// This is good for situations where the exact value is an approximation,
54
+ /// and thus there isn't anything accurate to display to the user.
17
55
Indeterminate ,
18
56
}
19
57
@@ -39,6 +77,16 @@ struct Format {
39
77
}
40
78
41
79
impl < ' cfg > Progress < ' cfg > {
80
+ /// Creates a new progress bar.
81
+ ///
82
+ /// The first parameter is the text displayed to the left of the bar, such
83
+ /// as "Fetching".
84
+ ///
85
+ /// The progress bar is not displayed until explicitly updated with one if
86
+ /// its methods.
87
+ ///
88
+ /// The progress bar may be created in a disabled state if the user has
89
+ /// disabled progress display (such as with the `--quiet` option).
42
90
pub fn with_style ( name : & str , style : ProgressStyle , cfg : & ' cfg Config ) -> Progress < ' cfg > {
43
91
// report no progress when -q (for quiet) or TERM=dumb are set
44
92
// or if running on Continuous Integration service like Travis where the
@@ -84,18 +132,33 @@ impl<'cfg> Progress<'cfg> {
84
132
}
85
133
}
86
134
135
+ /// Disables the progress bar, ensuring it won't be displayed.
87
136
pub fn disable ( & mut self ) {
88
137
self . state = None ;
89
138
}
90
139
140
+ /// Returns whether or not the progress bar is allowed to be displayed.
91
141
pub fn is_enabled ( & self ) -> bool {
92
142
self . state . is_some ( )
93
143
}
94
144
145
+ /// Creates a new `Progress` with the [`ProgressStyle::Percentage`] style.
146
+ ///
147
+ /// See [`Progress::with_style`] for more information.
95
148
pub fn new ( name : & str , cfg : & ' cfg Config ) -> Progress < ' cfg > {
96
149
Self :: with_style ( name, ProgressStyle :: Percentage , cfg)
97
150
}
98
151
152
+ /// Updates the state of the progress bar.
153
+ ///
154
+ /// * `cur` should be how far along the progress is.
155
+ /// * `max` is the maximum value for the progress bar.
156
+ /// * `msg` is a small piece of text to display at the end of the progress
157
+ /// bar. It will be truncated with `...` if it does not fit on the
158
+ /// terminal.
159
+ ///
160
+ /// This may not actually update the display if `tick` is being called too
161
+ /// quickly.
99
162
pub fn tick ( & mut self , cur : usize , max : usize , msg : & str ) -> CargoResult < ( ) > {
100
163
let s = match & mut self . state {
101
164
Some ( s) => s,
@@ -121,27 +184,48 @@ impl<'cfg> Progress<'cfg> {
121
184
s. tick ( cur, max, msg)
122
185
}
123
186
187
+ /// Updates the state of the progress bar.
188
+ ///
189
+ /// This is the same as [`Progress::tick`], but ignores rate throttling
190
+ /// and forces the display to be updated immediately.
191
+ ///
192
+ /// This may be useful for situations where you know you aren't calling
193
+ /// `tick` too fast, and accurate information is more important than
194
+ /// limiting the console update rate.
124
195
pub fn tick_now ( & mut self , cur : usize , max : usize , msg : & str ) -> CargoResult < ( ) > {
125
196
match self . state {
126
197
Some ( ref mut s) => s. tick ( cur, max, msg) ,
127
198
None => Ok ( ( ) ) ,
128
199
}
129
200
}
130
201
202
+ /// Returns whether or not updates are currently being throttled.
203
+ ///
204
+ /// This can be useful if computing the values for calling the
205
+ /// [`Progress::tick`] function may require some expensive work.
131
206
pub fn update_allowed ( & mut self ) -> bool {
132
207
match & mut self . state {
133
208
Some ( s) => s. throttle . allowed ( ) ,
134
209
None => false ,
135
210
}
136
211
}
137
212
213
+ /// Displays progress without a bar.
214
+ ///
215
+ /// The given `msg` is the text to display after the status message.
216
+ ///
217
+ /// Example: `Downloading 61 crates, remaining bytes: 28.0 MB`
218
+ ///
219
+ /// This does not have any rate limit throttling, so be careful about
220
+ /// calling it too often.
138
221
pub fn print_now ( & mut self , msg : & str ) -> CargoResult < ( ) > {
139
222
match & mut self . state {
140
223
Some ( s) => s. print ( "" , msg) ,
141
224
None => Ok ( ( ) ) ,
142
225
}
143
226
}
144
227
228
+ /// Clears the progress bar from the console.
145
229
pub fn clear ( & mut self ) {
146
230
if let Some ( ref mut s) = self . state {
147
231
s. clear ( ) ;
0 commit comments