]> git.proxmox.com Git - rustc.git/blame - vendor/prodash/src/traits.rs
New upstream version 1.72.1+dfsg1
[rustc.git] / vendor / prodash / src / traits.rs
CommitLineData
0a29b90c
FG
1use std::time::Instant;
2
3use crate::{messages::MessageLevel, progress, progress::Id, Unit};
4
fe692bf9
FG
5/// A trait for describing hierarchical progress.
6pub trait Progress: Send + Sync {
0a29b90c
FG
7 /// The type of progress returned by [`add_child()`][Progress::add_child()].
8 type SubProgress: Progress;
9
10 /// Adds a new child, whose parent is this instance, with the given `name`.
11 ///
12 /// This will make the child progress to appear contained in the parent progress.
13 /// Note that such progress does not have a stable identifier, which can be added
14 /// with [`add_child_with_id()`][Progress::add_child_with_id()] if desired.
15 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress;
16
17 /// Adds a new child, whose parent is this instance, with the given `name` and `id`.
18 ///
19 /// This will make the child progress to appear contained in the parent progress, and it can be identified
20 /// using `id`.
21 fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress;
22
23 /// Initialize the Item for receiving progress information.
24 ///
25 /// If `max` is `Some(…)`, it will be treated as upper bound. When progress is [set(…)](./struct.Item.html#method.set)
26 /// it should not exceed the given maximum.
27 /// If `max` is `None`, the progress is unbounded. Use this if the amount of work cannot accurately
28 /// be determined in advance.
29 ///
30 /// If `unit` is `Some(…)`, it is used for display purposes only. See `prodash::Unit` for more information.
31 ///
32 /// If both `unit` and `max` are `None`, the item will be reset to be equivalent to 'uninitialized'.
33 ///
34 /// If this method is never called, this `Progress` instance will serve as organizational unit, useful to add more structure
35 /// to the progress tree (e.g. a headline).
36 ///
37 /// **Note** that this method can be called multiple times, changing the bounded-ness and unit at will.
38 fn init(&mut self, max: Option<progress::Step>, unit: Option<Unit>);
39
40 /// Set the current progress to the given `step`. The cost of this call is negligible,
41 /// making manual throttling *not* necessary.
42 ///
43 /// **Note**: that this call has no effect unless `init(…)` was called before.
44 fn set(&mut self, step: progress::Step);
45
46 /// Returns the (cloned) unit associated with this Progress
47 fn unit(&self) -> Option<Unit> {
48 None
49 }
50
51 /// Returns the maximum about of items we expect, as provided with the `init(…)` call
52 fn max(&self) -> Option<progress::Step> {
53 None
54 }
55
56 /// Set the maximum value to `max` and return the old maximum value.
57 fn set_max(&mut self, _max: Option<progress::Step>) -> Option<progress::Step> {
58 None
59 }
60
61 /// Returns the current step, as controlled by `inc*(…)` calls
62 fn step(&self) -> progress::Step;
63
64 /// Increment the current progress to the given `step`.
65 /// The cost of this call is negligible, making manual throttling *not* necessary.
66 fn inc_by(&mut self, step: progress::Step);
67
68 /// Increment the current progress to the given 1. The cost of this call is negligible,
69 /// making manual throttling *not* necessary.
70 fn inc(&mut self) {
71 self.inc_by(1)
72 }
73
74 /// Set the name of the instance, altering the value given when crating it with `add_child(…)`
75 /// The progress is allowed to discard it.
76 fn set_name(&mut self, name: impl Into<String>);
77
78 /// Get the name of the instance as given when creating it with `add_child(…)`
79 /// The progress is allowed to not be named, thus there is no guarantee that a previously set names 'sticks'.
80 fn name(&self) -> Option<String>;
81
82 /// Get a stable identifier for the progress instance.
83 /// Note that it could be [unknown][crate::progress::UNKNOWN].
84 fn id(&self) -> Id;
85
86 /// Create a `message` of the given `level` and store it with the progress tree.
87 ///
88 /// Use this to provide additional,human-readable information about the progress
89 /// made, including indicating success or failure.
fe692bf9 90 fn message(&self, level: MessageLevel, message: impl Into<String>);
0a29b90c
FG
91
92 /// If available, return an atomic counter for direct access to the underlying state.
93 ///
94 /// This is useful if multiple threads want to access the same progress, without the need
95 /// for provide each their own progress and aggregating the result.
96 fn counter(&self) -> Option<StepShared> {
97 None
98 }
99
100 /// Create a message providing additional information about the progress thus far.
fe692bf9 101 fn info(&self, message: impl Into<String>) {
0a29b90c
FG
102 self.message(MessageLevel::Info, message)
103 }
104 /// Create a message indicating the task is done successfully
fe692bf9 105 fn done(&self, message: impl Into<String>) {
0a29b90c
FG
106 self.message(MessageLevel::Success, message)
107 }
108 /// Create a message indicating the task failed
fe692bf9 109 fn fail(&self, message: impl Into<String>) {
0a29b90c
FG
110 self.message(MessageLevel::Failure, message)
111 }
112 /// A shorthand to print throughput information
fe692bf9 113 fn show_throughput(&self, start: Instant) {
0a29b90c
FG
114 let step = self.step();
115 match self.unit() {
116 Some(unit) => self.show_throughput_with(start, step, unit, MessageLevel::Info),
117 None => {
118 let elapsed = start.elapsed().as_secs_f32();
119 let steps_per_second = (step as f32 / elapsed) as progress::Step;
120 self.info(format!(
121 "done {} items in {:.02}s ({} items/s)",
122 step, elapsed, steps_per_second
123 ))
124 }
125 };
126 }
127
128 /// A shorthand to print throughput information, with the given step and unit, and message level.
fe692bf9
FG
129 fn show_throughput_with(&self, start: Instant, step: progress::Step, unit: Unit, level: MessageLevel) {
130 use std::fmt::Write;
131 let elapsed = start.elapsed().as_secs_f32();
132 let steps_per_second = (step as f32 / elapsed) as progress::Step;
133 let mut buf = String::with_capacity(128);
134 let unit = unit.as_display_value();
135 let push_unit = |buf: &mut String| {
136 buf.push(' ');
137 let len_before_unit = buf.len();
138 unit.display_unit(buf, step).ok();
139 if buf.len() == len_before_unit {
140 buf.pop();
141 }
142 };
143
144 buf.push_str("done ");
145 unit.display_current_value(&mut buf, step, None).ok();
146 push_unit(&mut buf);
147
148 buf.write_fmt(format_args!(" in {:.02}s (", elapsed)).ok();
149 unit.display_current_value(&mut buf, steps_per_second, None).ok();
150 push_unit(&mut buf);
151 buf.push_str("/s)");
152
153 self.message(level, buf);
154 }
155}
156
157/// A trait for describing non-hierarchical progress.
158///
159/// It differs by not being able to add child progress dynamically, but in turn is object safe. It's recommended to
160/// use this trait whenever there is no need to add child progress, at the leaf of a computation.
161// NOTE: keep this in-sync with `Progress`.
162pub trait RawProgress: Send + Sync {
163 /// Initialize the Item for receiving progress information.
164 ///
165 /// If `max` is `Some(…)`, it will be treated as upper bound. When progress is [set(…)](./struct.Item.html#method.set)
166 /// it should not exceed the given maximum.
167 /// If `max` is `None`, the progress is unbounded. Use this if the amount of work cannot accurately
168 /// be determined in advance.
169 ///
170 /// If `unit` is `Some(…)`, it is used for display purposes only. See `prodash::Unit` for more information.
171 ///
172 /// If both `unit` and `max` are `None`, the item will be reset to be equivalent to 'uninitialized'.
173 ///
174 /// If this method is never called, this `Progress` instance will serve as organizational unit, useful to add more structure
175 /// to the progress tree (e.g. a headline).
176 ///
177 /// **Note** that this method can be called multiple times, changing the bounded-ness and unit at will.
178 fn init(&mut self, max: Option<progress::Step>, unit: Option<Unit>);
179
180 /// Set the current progress to the given `step`. The cost of this call is negligible,
181 /// making manual throttling *not* necessary.
182 ///
183 /// **Note**: that this call has no effect unless `init(…)` was called before.
184 fn set(&mut self, step: progress::Step);
185
186 /// Returns the (cloned) unit associated with this Progress
187 fn unit(&self) -> Option<Unit> {
188 None
189 }
190
191 /// Returns the maximum about of items we expect, as provided with the `init(…)` call
192 fn max(&self) -> Option<progress::Step> {
193 None
194 }
195
196 /// Set the maximum value to `max` and return the old maximum value.
197 fn set_max(&mut self, _max: Option<progress::Step>) -> Option<progress::Step> {
198 None
199 }
200
201 /// Returns the current step, as controlled by `inc*(…)` calls
202 fn step(&self) -> progress::Step;
203
204 /// Increment the current progress to the given `step`.
205 /// The cost of this call is negligible, making manual throttling *not* necessary.
206 fn inc_by(&mut self, step: progress::Step);
207
208 /// Increment the current progress to the given 1. The cost of this call is negligible,
209 /// making manual throttling *not* necessary.
210 fn inc(&mut self) {
211 self.inc_by(1)
212 }
213
214 /// Set the name of the instance, altering the value given when crating it with `add_child(…)`
215 /// The progress is allowed to discard it.
216 fn set_name(&mut self, name: String);
217
218 /// Get the name of the instance as given when creating it with `add_child(…)`
219 /// The progress is allowed to not be named, thus there is no guarantee that a previously set names 'sticks'.
220 fn name(&self) -> Option<String>;
221
222 /// Get a stable identifier for the progress instance.
223 /// Note that it could be [unknown][crate::progress::UNKNOWN].
224 fn id(&self) -> Id;
225
226 /// Create a `message` of the given `level` and store it with the progress tree.
227 ///
228 /// Use this to provide additional,human-readable information about the progress
229 /// made, including indicating success or failure.
230 fn message(&self, level: MessageLevel, message: String);
231
232 /// If available, return an atomic counter for direct access to the underlying state.
233 ///
234 /// This is useful if multiple threads want to access the same progress, without the need
235 /// for provide each their own progress and aggregating the result.
236 fn counter(&self) -> Option<StepShared> {
237 None
238 }
239
240 /// Create a message providing additional information about the progress thus far.
241 fn info(&self, message: String) {
242 self.message(MessageLevel::Info, message)
243 }
244 /// Create a message indicating the task is done successfully
245 fn done(&self, message: String) {
246 self.message(MessageLevel::Success, message)
247 }
248 /// Create a message indicating the task failed
249 fn fail(&self, message: String) {
250 self.message(MessageLevel::Failure, message)
251 }
252 /// A shorthand to print throughput information
253 fn show_throughput(&self, start: Instant) {
254 let step = self.step();
255 match self.unit() {
256 Some(unit) => self.show_throughput_with(start, step, unit, MessageLevel::Info),
257 None => {
258 let elapsed = start.elapsed().as_secs_f32();
259 let steps_per_second = (step as f32 / elapsed) as progress::Step;
260 self.info(format!(
261 "done {} items in {:.02}s ({} items/s)",
262 step, elapsed, steps_per_second
263 ))
264 }
265 };
266 }
267
268 /// A shorthand to print throughput information, with the given step and unit, and message level.
269 fn show_throughput_with(&self, start: Instant, step: progress::Step, unit: Unit, level: MessageLevel) {
0a29b90c
FG
270 use std::fmt::Write;
271 let elapsed = start.elapsed().as_secs_f32();
272 let steps_per_second = (step as f32 / elapsed) as progress::Step;
273 let mut buf = String::with_capacity(128);
274 let unit = unit.as_display_value();
275 let push_unit = |buf: &mut String| {
276 buf.push(' ');
277 let len_before_unit = buf.len();
278 unit.display_unit(buf, step).ok();
279 if buf.len() == len_before_unit {
280 buf.pop();
281 }
282 };
283
284 buf.push_str("done ");
285 unit.display_current_value(&mut buf, step, None).ok();
286 push_unit(&mut buf);
287
288 buf.write_fmt(format_args!(" in {:.02}s (", elapsed)).ok();
289 unit.display_current_value(&mut buf, steps_per_second, None).ok();
290 push_unit(&mut buf);
291 buf.push_str("/s)");
292
293 self.message(level, buf);
294 }
295}
296
297use crate::{
298 messages::{Message, MessageCopyState},
299 progress::StepShared,
300};
301
302/// The top-level root as weak handle, which needs an upgrade to become a usable root.
303///
304/// If the underlying reference isn't present anymore, such upgrade will fail permanently.
305pub trait WeakRoot {
306 /// The type implementing the `Root` trait
307 type Root: Root;
308
309 /// Equivalent to `std::sync::Weak::upgrade()`.
310 fn upgrade(&self) -> Option<Self::Root>;
311}
312
313/// The top level of a progress task hierarchy, with `progress::Task`s identified with `progress::Key`s
314pub trait Root {
315 /// The type implementing the `WeakRoot` trait
316 type WeakRoot: WeakRoot;
317
318 /// Returns the maximum amount of messages we can keep before overwriting older ones.
319 fn messages_capacity(&self) -> usize;
320
321 /// Returns the current amount of tasks underneath the root, transitively.
322 /// **Note** that this is at most a guess as tasks can be added and removed in parallel.
323 fn num_tasks(&self) -> usize;
324
325 /// Copy the entire progress tree into the given `out` vector, so that
326 /// it can be traversed from beginning to end in order of hierarchy.
327 /// The `out` vec will be cleared automatically.
328 fn sorted_snapshot(&self, out: &mut Vec<(progress::Key, progress::Task)>);
329
330 /// Copy all messages from the internal ring buffer into the given `out`
331 /// vector. Messages are ordered from oldest to newest.
332 fn copy_messages(&self, out: &mut Vec<Message>);
333
334 /// Copy only new messages from the internal ring buffer into the given `out`
335 /// vector. Messages are ordered from oldest to newest.
336 fn copy_new_messages(&self, out: &mut Vec<Message>, prev: Option<MessageCopyState>) -> MessageCopyState;
337
338 /// Similar to `Arc::downgrade()`
339 fn downgrade(&self) -> Self::WeakRoot;
340}
341
342mod impls {
343 use std::{
344 ops::{Deref, DerefMut},
345 time::Instant,
346 };
347
fe692bf9 348 use crate::traits::RawProgress;
0a29b90c
FG
349 use crate::{
350 messages::MessageLevel,
351 progress::{Id, Step, StepShared},
352 Progress, Unit,
353 };
354
fe692bf9
FG
355 impl<T> RawProgress for T
356 where
357 T: Progress,
358 {
359 fn init(&mut self, max: Option<Step>, unit: Option<Unit>) {
360 <T as Progress>::init(self, max, unit)
361 }
362
363 fn set(&mut self, step: Step) {
364 <T as Progress>::set(self, step)
365 }
366
367 fn unit(&self) -> Option<Unit> {
368 <T as Progress>::unit(self)
369 }
370
371 fn max(&self) -> Option<Step> {
372 <T as Progress>::max(self)
373 }
374
375 fn set_max(&mut self, max: Option<Step>) -> Option<Step> {
376 <T as Progress>::set_max(self, max)
377 }
378
379 fn step(&self) -> Step {
380 <T as Progress>::step(self)
381 }
382
383 fn inc_by(&mut self, step: Step) {
384 <T as Progress>::inc_by(self, step)
385 }
386
387 fn inc(&mut self) {
388 <T as Progress>::inc(self)
389 }
390
391 fn set_name(&mut self, name: String) {
392 <T as Progress>::set_name(self, name)
393 }
394
395 fn name(&self) -> Option<String> {
396 <T as Progress>::name(self)
397 }
398
399 fn id(&self) -> Id {
400 <T as Progress>::id(self)
401 }
402
403 fn message(&self, level: MessageLevel, message: String) {
404 <T as Progress>::message(self, level, message)
405 }
406
407 fn counter(&self) -> Option<StepShared> {
408 <T as Progress>::counter(self)
409 }
410
411 fn info(&self, message: String) {
412 <T as Progress>::info(self, message)
413 }
414
415 fn done(&self, message: String) {
416 <T as Progress>::done(self, message)
417 }
418
419 fn fail(&self, message: String) {
420 <T as Progress>::fail(self, message)
421 }
422
423 fn show_throughput(&self, start: Instant) {
424 <T as Progress>::show_throughput(self, start)
425 }
426
427 fn show_throughput_with(&self, start: Instant, step: Step, unit: Unit, level: MessageLevel) {
428 <T as Progress>::show_throughput_with(self, start, step, unit, level)
429 }
430 }
431
0a29b90c
FG
432 impl<'a, T> Progress for &'a mut T
433 where
434 T: Progress,
435 {
436 type SubProgress = <T as Progress>::SubProgress;
437
438 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress {
439 self.deref_mut().add_child(name)
440 }
441
442 fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress {
443 self.deref_mut().add_child_with_id(name, id)
444 }
445
446 fn init(&mut self, max: Option<Step>, unit: Option<Unit>) {
447 self.deref_mut().init(max, unit)
448 }
449
450 fn set(&mut self, step: Step) {
451 self.deref_mut().set(step)
452 }
453
454 fn unit(&self) -> Option<Unit> {
455 self.deref().unit()
456 }
457
458 fn max(&self) -> Option<Step> {
459 self.deref().max()
460 }
461
462 fn set_max(&mut self, max: Option<Step>) -> Option<Step> {
463 self.deref_mut().set_max(max)
464 }
465
466 fn step(&self) -> Step {
467 self.deref().step()
468 }
469
470 fn inc_by(&mut self, step: Step) {
471 self.deref_mut().inc_by(step)
472 }
473
474 fn inc(&mut self) {
475 self.deref_mut().inc()
476 }
477
478 fn set_name(&mut self, name: impl Into<String>) {
479 self.deref_mut().set_name(name)
480 }
481
482 fn name(&self) -> Option<String> {
483 self.deref().name()
484 }
485
486 fn id(&self) -> Id {
fe692bf9 487 self.deref().id()
0a29b90c
FG
488 }
489
fe692bf9
FG
490 fn message(&self, level: MessageLevel, message: impl Into<String>) {
491 self.deref().message(level, message)
0a29b90c
FG
492 }
493
494 fn counter(&self) -> Option<StepShared> {
495 self.deref().counter()
496 }
497
fe692bf9
FG
498 fn info(&self, message: impl Into<String>) {
499 self.deref().info(message)
0a29b90c
FG
500 }
501
fe692bf9
FG
502 fn done(&self, message: impl Into<String>) {
503 self.deref().done(message)
0a29b90c
FG
504 }
505
fe692bf9
FG
506 fn fail(&self, message: impl Into<String>) {
507 self.deref().fail(message)
0a29b90c
FG
508 }
509
fe692bf9
FG
510 fn show_throughput(&self, start: Instant) {
511 self.deref().show_throughput(start)
0a29b90c
FG
512 }
513
fe692bf9
FG
514 fn show_throughput_with(&self, start: Instant, step: Step, unit: Unit, level: MessageLevel) {
515 self.deref().show_throughput_with(start, step, unit, level)
0a29b90c
FG
516 }
517 }
518}