@@ -2,7 +2,7 @@ use std::time::Instant;
2
2
3
3
use crate :: { messages:: MessageLevel , progress, progress:: Id , Unit } ;
4
4
5
- /// A trait for describing hierarchical process .
5
+ /// A trait for describing hierarchical progress .
6
6
pub trait Progress : Send {
7
7
/// The type of progress returned by [`add_child()`][Progress::add_child()].
8
8
type SubProgress : Progress ;
@@ -154,6 +154,146 @@ pub trait Progress: Send {
154
154
}
155
155
}
156
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`.
162
+ pub trait RawProgress : Send {
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 ( & mut 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 ( & mut self , message : String ) {
242
+ self . message ( MessageLevel :: Info , message)
243
+ }
244
+ /// Create a message indicating the task is done successfully
245
+ fn done ( & mut self , message : String ) {
246
+ self . message ( MessageLevel :: Success , message)
247
+ }
248
+ /// Create a message indicating the task failed
249
+ fn fail ( & mut self , message : String ) {
250
+ self . message ( MessageLevel :: Failure , message)
251
+ }
252
+ /// A shorthand to print throughput information
253
+ fn show_throughput ( & mut 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 ( & mut self , start : Instant , step : progress:: Step , unit : Unit , level : MessageLevel ) {
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
+
157
297
use crate :: {
158
298
messages:: { Message , MessageCopyState } ,
159
299
progress:: StepShared ,
@@ -205,12 +345,90 @@ mod impls {
205
345
time:: Instant ,
206
346
} ;
207
347
348
+ use crate :: traits:: RawProgress ;
208
349
use crate :: {
209
350
messages:: MessageLevel ,
210
351
progress:: { Id , Step , StepShared } ,
211
352
Progress , Unit ,
212
353
} ;
213
354
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 ( & mut 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 ( & mut self , message : String ) {
412
+ <T as Progress >:: info ( self , message)
413
+ }
414
+
415
+ fn done ( & mut self , message : String ) {
416
+ <T as Progress >:: done ( self , message)
417
+ }
418
+
419
+ fn fail ( & mut self , message : String ) {
420
+ <T as Progress >:: fail ( self , message)
421
+ }
422
+
423
+ fn show_throughput ( & mut self , start : Instant ) {
424
+ <T as Progress >:: show_throughput ( self , start)
425
+ }
426
+
427
+ fn show_throughput_with ( & mut self , start : Instant , step : Step , unit : Unit , level : MessageLevel ) {
428
+ <T as Progress >:: show_throughput_with ( self , start, step, unit, level)
429
+ }
430
+ }
431
+
214
432
impl < ' a , T > Progress for & ' a mut T
215
433
where
216
434
T : Progress ,
@@ -266,7 +484,7 @@ mod impls {
266
484
}
267
485
268
486
fn id ( & self ) -> Id {
269
- todo ! ( )
487
+ self . deref ( ) . id ( )
270
488
}
271
489
272
490
fn message ( & mut self , level : MessageLevel , message : impl Into < String > ) {
0 commit comments