diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/prodash/src | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/prodash/src')
-rw-r--r-- | vendor/prodash/src/lib.rs | 5 | ||||
-rw-r--r-- | vendor/prodash/src/progress/log.rs | 101 | ||||
-rw-r--r-- | vendor/prodash/src/progress/mod.rs | 5 | ||||
-rw-r--r-- | vendor/prodash/src/progress/utils.rs | 258 | ||||
-rw-r--r-- | vendor/prodash/src/render/line/engine.rs | 15 | ||||
-rw-r--r-- | vendor/prodash/src/traits.rs | 495 | ||||
-rw-r--r-- | vendor/prodash/src/tree/item.rs | 76 |
7 files changed, 547 insertions, 408 deletions
diff --git a/vendor/prodash/src/lib.rs b/vendor/prodash/src/lib.rs index e3eb6042c..8b35afcad 100644 --- a/vendor/prodash/src/lib.rs +++ b/vendor/prodash/src/lib.rs @@ -64,7 +64,10 @@ pub mod messages; pub mod progress; mod traits; -pub use traits::{Progress, RawProgress, Root, WeakRoot}; +pub use traits::{ + BoxedDynNestedProgress, BoxedProgress, Count, DynNestedProgress, DynNestedProgressToNestedProgress, NestedProgress, + Progress, Root, WeakRoot, +}; mod throughput; pub use crate::throughput::Throughput; diff --git a/vendor/prodash/src/progress/log.rs b/vendor/prodash/src/progress/log.rs index 6fb16f109..95d538cbf 100644 --- a/vendor/prodash/src/progress/log.rs +++ b/vendor/prodash/src/progress/log.rs @@ -9,10 +9,10 @@ use std::{ use crate::{ messages::MessageLevel, progress::{Id, Step, StepShared}, - Progress, Unit, + Count, NestedProgress, Progress, Unit, }; -/// A [`Progress`] implementation which displays progress as it happens without the use of a renderer. +/// A [`NestedProgress`] implementation which displays progress as it happens without the use of a renderer. /// /// Note that this incurs considerable performance cost as each progress calls ends up getting the system time /// to see if progress information should actually be emitted. @@ -21,7 +21,7 @@ pub struct Log { id: Id, max: Option<usize>, unit: Option<Unit>, - step: usize, + step: StepShared, current_level: usize, max_level: usize, trigger: Arc<AtomicBool>, @@ -50,43 +50,19 @@ impl Log { current_level: 0, max_level: max_level.unwrap_or(usize::MAX), max: None, - step: 0, + step: Default::default(), unit: None, trigger, } } } -impl Progress for Log { - type SubProgress = Log; - - fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { - self.add_child_with_id(name, crate::progress::UNKNOWN) - } - - fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { - Log { - name: format!("{}{}{}", self.name, SEP, Into::<String>::into(name)), - id, - current_level: self.current_level + 1, - max_level: self.max_level, - step: 0, - max: None, - unit: None, - trigger: Arc::clone(&self.trigger), - } - } - - fn init(&mut self, max: Option<usize>, unit: Option<Unit>) { - self.max = max; - self.unit = unit; - } - - fn set(&mut self, step: usize) { - self.step = step; +impl Log { + fn maybe_log(&self) { if self.current_level > self.max_level { return; } + let step = self.step(); if self.trigger.swap(false, Ordering::Relaxed) { match (self.max, &self.unit) { (max, Some(unit)) => log::info!("{} → {}", self.name, unit.display(step, max, None)), @@ -95,12 +71,38 @@ impl Progress for Log { } } } +} + +impl Count for Log { + fn set(&self, step: Step) { + self.step.store(step, Ordering::SeqCst); + self.maybe_log() + } + fn step(&self) -> usize { + self.step.load(Ordering::Relaxed) + } + + fn inc_by(&self, step: Step) { + self.step.fetch_add(step, Ordering::Relaxed); + self.maybe_log() + } + + fn counter(&self) -> StepShared { + self.step.clone() + } +} + +impl Progress for Log { + fn init(&mut self, max: Option<Step>, unit: Option<Unit>) { + self.max = max; + self.unit = unit; + } fn unit(&self) -> Option<Unit> { self.unit.clone() } - fn max(&self) -> Option<usize> { + fn max(&self) -> Option<Step> { self.max } @@ -110,16 +112,7 @@ impl Progress for Log { prev } - fn step(&self) -> usize { - self.step - } - - fn inc_by(&mut self, step: usize) { - self.set(self.step + step) - } - - fn set_name(&mut self, name: impl Into<String>) { - let name = name.into(); + fn set_name(&mut self, name: String) { self.name = self .name .split("::") @@ -136,16 +129,32 @@ impl Progress for Log { self.id } - fn message(&self, level: MessageLevel, message: impl Into<String>) { - let message: String = message.into(); + fn message(&self, level: MessageLevel, message: String) { match level { MessageLevel::Info => log::info!("ℹ{} → {}", self.name, message), MessageLevel::Failure => log::error!("𐄂{} → {}", self.name, message), MessageLevel::Success => log::info!("✓{} → {}", self.name, message), } } +} + +impl NestedProgress for Log { + type SubProgress = Log; + + fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { + self.add_child_with_id(name, crate::progress::UNKNOWN) + } - fn counter(&self) -> Option<StepShared> { - None + fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { + Log { + name: format!("{}{}{}", self.name, SEP, Into::<String>::into(name)), + id, + current_level: self.current_level + 1, + max_level: self.max_level, + step: Default::default(), + max: None, + unit: None, + trigger: Arc::clone(&self.trigger), + } } } diff --git a/vendor/prodash/src/progress/mod.rs b/vendor/prodash/src/progress/mod.rs index 842bbb6e1..e16bc2acc 100644 --- a/vendor/prodash/src/progress/mod.rs +++ b/vendor/prodash/src/progress/mod.rs @@ -37,8 +37,11 @@ pub const UNKNOWN: Id = *b"\0\0\0\0"; /// The amount of steps a progress can make pub type Step = usize; +/// The amount of steps a progress can make, for threadsafe counting. +pub type AtomicStep = AtomicUsize; + /// As step, but shareable. -pub type StepShared = Arc<AtomicUsize>; +pub type StepShared = Arc<AtomicStep>; /// Indicate whether a progress can or cannot be made. #[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] diff --git a/vendor/prodash/src/progress/utils.rs b/vendor/prodash/src/progress/utils.rs index 3fd6c64bf..f0b027178 100644 --- a/vendor/prodash/src/progress/utils.rs +++ b/vendor/prodash/src/progress/utils.rs @@ -1,34 +1,31 @@ -use crate::{messages::MessageLevel, progress::Id, Progress, Unit}; +use crate::{messages::MessageLevel, progress::Id, Count, NestedProgress, Progress, Unit}; +use std::sync::atomic::AtomicUsize; +use std::sync::Arc; -/// An implementation of [`Progress`] which discards all calls. +/// An implementation of [`NestedProgress`] which discards all calls. pub struct Discard; -impl Progress for Discard { - type SubProgress = Discard; +impl Count for Discard { + fn set(&self, _step: usize) {} - fn add_child(&mut self, _name: impl Into<String>) -> Self::SubProgress { - Discard + fn step(&self) -> usize { + 0 } - fn add_child_with_id(&mut self, _name: impl Into<String>, _id: Id) -> Self::SubProgress { - Discard + fn inc_by(&self, _step: usize) {} + + fn counter(&self) -> StepShared { + Arc::new(AtomicUsize::default()) } +} +impl Progress for Discard { fn init(&mut self, _max: Option<usize>, _unit: Option<Unit>) {} - fn set(&mut self, _step: usize) {} - fn set_max(&mut self, _max: Option<Step>) -> Option<Step> { None } - - fn step(&self) -> usize { - 0 - } - - fn inc_by(&mut self, _step: usize) {} - - fn set_name(&mut self, _name: impl Into<String>) {} + fn set_name(&mut self, _name: String) {} fn name(&self) -> Option<String> { None @@ -38,14 +35,22 @@ impl Progress for Discard { crate::progress::UNKNOWN } - fn message(&self, _level: MessageLevel, _message: impl Into<String>) {} + fn message(&self, _level: MessageLevel, _message: String) {} +} + +impl NestedProgress for Discard { + type SubProgress = Self; - fn counter(&self) -> Option<StepShared> { - None + fn add_child(&mut self, _name: impl Into<String>) -> Self { + Discard + } + + fn add_child_with_id(&mut self, _name: impl Into<String>, _id: Id) -> Self { + Discard } } -/// An implementation of [`Progress`] showing either one or the other implementation. +/// An implementation of [`NestedProgress`] showing either one or the other implementation. /// /// Useful in conjunction with [`Discard`] and a working implementation, making it as a form of `Option<Progress>` which /// can be passed to methods requiring `impl Progress`. @@ -56,38 +61,46 @@ pub enum Either<L, R> { Right(R), } -impl<L, R> Progress for Either<L, R> +impl<L, R> Count for Either<L, R> where - L: Progress, - R: Progress, + L: Count, + R: Count, { - type SubProgress = Either<L::SubProgress, R::SubProgress>; - - fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { + fn set(&self, step: usize) { match self { - Either::Left(l) => Either::Left(l.add_child(name)), - Either::Right(r) => Either::Right(r.add_child(name)), + Either::Left(l) => l.set(step), + Either::Right(r) => r.set(step), } } - - fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { + fn step(&self) -> usize { match self { - Either::Left(l) => Either::Left(l.add_child_with_id(name, id)), - Either::Right(r) => Either::Right(r.add_child_with_id(name, id)), + Either::Left(l) => l.step(), + Either::Right(r) => r.step(), } } - - fn init(&mut self, max: Option<usize>, unit: Option<Unit>) { + fn inc_by(&self, step: usize) { match self { - Either::Left(l) => l.init(max, unit), - Either::Right(r) => r.init(max, unit), + Either::Left(l) => l.inc_by(step), + Either::Right(r) => r.inc_by(step), } } + fn counter(&self) -> StepShared { + match self { + Either::Left(l) => l.counter(), + Either::Right(r) => r.counter(), + } + } +} - fn set(&mut self, step: usize) { +impl<L, R> Progress for Either<L, R> +where + L: Progress, + R: Progress, +{ + fn init(&mut self, max: Option<usize>, unit: Option<Unit>) { match self { - Either::Left(l) => l.set(step), - Either::Right(r) => r.set(step), + Either::Left(l) => l.init(max, unit), + Either::Right(r) => r.init(max, unit), } } @@ -112,21 +125,7 @@ where } } - fn step(&self) -> usize { - match self { - Either::Left(l) => l.step(), - Either::Right(r) => r.step(), - } - } - - fn inc_by(&mut self, step: usize) { - match self { - Either::Left(l) => l.inc_by(step), - Either::Right(r) => r.inc_by(step), - } - } - - fn set_name(&mut self, name: impl Into<String>) { + fn set_name(&mut self, name: String) { match self { Either::Left(l) => l.set_name(name), Either::Right(r) => r.set_name(name), @@ -141,20 +140,38 @@ where } fn id(&self) -> Id { - todo!() + match self { + Either::Left(l) => l.id(), + Either::Right(r) => r.id(), + } } - fn message(&self, level: MessageLevel, message: impl Into<String>) { + fn message(&self, level: MessageLevel, message: String) { match self { Either::Left(l) => l.message(level, message), Either::Right(r) => r.message(level, message), } } +} - fn counter(&self) -> Option<StepShared> { +impl<L, R> NestedProgress for Either<L, R> +where + L: NestedProgress, + R: NestedProgress, +{ + type SubProgress = Either<L::SubProgress, R::SubProgress>; + + fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { match self { - Either::Left(l) => l.counter(), - Either::Right(r) => r.counter(), + Either::Left(l) => Either::Left(l.add_child(name)), + Either::Right(r) => Either::Right(r.add_child(name)), + } + } + + fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { + match self { + Either::Left(l) => Either::Left(l.add_child_with_id(name, id)), + Either::Right(r) => Either::Right(r.add_child_with_id(name, id)), } } } @@ -164,7 +181,7 @@ pub struct DoOrDiscard<T>(Either<T, Discard>); impl<T> From<Option<T>> for DoOrDiscard<T> where - T: Progress, + T: NestedProgress, { fn from(p: Option<T>) -> Self { match p { @@ -174,8 +191,8 @@ where } } -impl<T: Progress> DoOrDiscard<T> { - /// Obtain either the original [`Progress`] implementation or `None`. +impl<T: NestedProgress> DoOrDiscard<T> { + /// Obtain either the original [`NestedProgress`] implementation or `None`. pub fn into_inner(self) -> Option<T> { match self { DoOrDiscard(Either::Left(p)) => Some(p), @@ -183,7 +200,7 @@ impl<T: Progress> DoOrDiscard<T> { } } - /// Take out the implementation of [`Progress`] and replace it with [`Discard`]. + /// Take out the implementation of [`NestedProgress`] and replace it with [`Discard`]. pub fn take(&mut self) -> Option<T> { let this = std::mem::replace(self, DoOrDiscard::from(None)); match this { @@ -193,28 +210,34 @@ impl<T: Progress> DoOrDiscard<T> { } } -impl<T> Progress for DoOrDiscard<T> +impl<T> Count for DoOrDiscard<T> where - T: Progress, + T: Count, { - type SubProgress = DoOrDiscard<T::SubProgress>; + fn set(&self, step: usize) { + self.0.set(step) + } + fn step(&self) -> usize { + self.0.step() + } - fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { - DoOrDiscard(self.0.add_child(name)) + fn inc_by(&self, step: usize) { + self.0.inc_by(step) } - fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { - DoOrDiscard(self.0.add_child_with_id(name, id)) + fn counter(&self) -> StepShared { + self.0.counter() } +} +impl<T> Progress for DoOrDiscard<T> +where + T: Progress, +{ fn init(&mut self, max: Option<usize>, unit: Option<Unit>) { self.0.init(max, unit) } - fn set(&mut self, step: usize) { - self.0.set(step) - } - fn unit(&self) -> Option<Unit> { self.0.unit() } @@ -227,15 +250,7 @@ where self.0.set_max(max) } - fn step(&self) -> usize { - self.0.step() - } - - fn inc_by(&mut self, step: usize) { - self.0.inc_by(step) - } - - fn set_name(&mut self, name: impl Into<String>) { + fn set_name(&mut self, name: String) { self.0.set_name(name); } @@ -247,12 +262,23 @@ where self.0.id() } - fn message(&self, level: MessageLevel, message: impl Into<String>) { + fn message(&self, level: MessageLevel, message: String) { self.0.message(level, message) } +} - fn counter(&self) -> Option<StepShared> { - self.0.counter() +impl<T> NestedProgress for DoOrDiscard<T> +where + T: NestedProgress, +{ + type SubProgress = DoOrDiscard<T::SubProgress>; + + fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { + DoOrDiscard(self.0.add_child(name)) + } + + fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { + DoOrDiscard(self.0.add_child_with_id(name, id)) } } @@ -261,32 +287,36 @@ use std::time::Instant; use crate::progress::{Step, StepShared}; /// Emit a message with throughput information when the instance is dropped. -pub struct ThroughputOnDrop<T: Progress>(T, Instant); +pub struct ThroughputOnDrop<T: NestedProgress>(T, Instant); -impl<T: Progress> ThroughputOnDrop<T> { - /// Create a new instance by providing the `inner` [`Progress`] implementation. +impl<T: NestedProgress> ThroughputOnDrop<T> { + /// Create a new instance by providing the `inner` [`NestedProgress`] implementation. pub fn new(inner: T) -> Self { ThroughputOnDrop(inner, Instant::now()) } } -impl<T: Progress> Progress for ThroughputOnDrop<T> { - type SubProgress = T::SubProgress; +impl<T: NestedProgress> Count for ThroughputOnDrop<T> { + fn set(&self, step: usize) { + self.0.set(step) + } - fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { - self.0.add_child(name) + fn step(&self) -> usize { + self.0.step() } - fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { - self.0.add_child_with_id(name, id) + fn inc_by(&self, step: usize) { + self.0.inc_by(step) } - fn init(&mut self, max: Option<usize>, unit: Option<Unit>) { - self.0.init(max, unit) + fn counter(&self) -> StepShared { + self.0.counter() } +} - fn set(&mut self, step: usize) { - self.0.set(step) +impl<T: NestedProgress> Progress for ThroughputOnDrop<T> { + fn init(&mut self, max: Option<usize>, unit: Option<Unit>) { + self.0.init(max, unit) } fn unit(&self) -> Option<Unit> { @@ -301,15 +331,7 @@ impl<T: Progress> Progress for ThroughputOnDrop<T> { self.0.set_max(max) } - fn step(&self) -> usize { - self.0.step() - } - - fn inc_by(&mut self, step: usize) { - self.0.inc_by(step) - } - - fn set_name(&mut self, name: impl Into<String>) { + fn set_name(&mut self, name: String) { self.0.set_name(name) } @@ -321,16 +343,24 @@ impl<T: Progress> Progress for ThroughputOnDrop<T> { self.0.id() } - fn message(&self, level: MessageLevel, message: impl Into<String>) { + fn message(&self, level: MessageLevel, message: String) { self.0.message(level, message) } +} - fn counter(&self) -> Option<StepShared> { - self.0.counter() +impl<T: NestedProgress> NestedProgress for ThroughputOnDrop<T> { + type SubProgress = ThroughputOnDrop<T::SubProgress>; + + fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { + ThroughputOnDrop::new(self.0.add_child(name)) + } + + fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { + ThroughputOnDrop::new(self.0.add_child_with_id(name, id)) } } -impl<T: Progress> Drop for ThroughputOnDrop<T> { +impl<T: NestedProgress> Drop for ThroughputOnDrop<T> { fn drop(&mut self) { self.0.show_throughput(self.1) } diff --git a/vendor/prodash/src/render/line/engine.rs b/vendor/prodash/src/render/line/engine.rs index d440fb159..c44d5991f 100644 --- a/vendor/prodash/src/render/line/engine.rs +++ b/vendor/prodash/src/render/line/engine.rs @@ -74,16 +74,6 @@ pub enum StreamKind { Stderr, } -#[cfg(feature = "render-line-autoconfigure")] -impl From<StreamKind> for atty::Stream { - fn from(s: StreamKind) -> Self { - match s { - StreamKind::Stdout => atty::Stream::Stdout, - StreamKind::Stderr => atty::Stream::Stderr, - } - } -} - /// Convenience impl Options { /// Automatically configure (and overwrite) the following fields based on terminal configuration. @@ -94,7 +84,10 @@ impl Options { /// * hide-cursor (based on presence of 'signal-hook' feature. #[cfg(feature = "render-line-autoconfigure")] pub fn auto_configure(mut self, output: StreamKind) -> Self { - self.output_is_terminal = atty::is(output.into()); + self.output_is_terminal = match output { + StreamKind::Stdout => is_terminal::is_terminal(std::io::stdout()), + StreamKind::Stderr => is_terminal::is_terminal(std::io::stderr()), + }; self.colored = self.output_is_terminal && crosstermion::color::allowed(); self.terminal_dimensions = crosstermion::terminal::size().unwrap_or((80, 20)); #[cfg(feature = "signal-hook")] diff --git a/vendor/prodash/src/traits.rs b/vendor/prodash/src/traits.rs index 1aac1d43a..602915bc2 100644 --- a/vendor/prodash/src/traits.rs +++ b/vendor/prodash/src/traits.rs @@ -3,9 +3,9 @@ use std::time::Instant; use crate::{messages::MessageLevel, progress, progress::Id, Unit}; /// A trait for describing hierarchical progress. -pub trait Progress: Send + Sync { +pub trait NestedProgress: Progress { /// The type of progress returned by [`add_child()`][Progress::add_child()]. - type SubProgress: Progress; + type SubProgress: NestedProgress; /// Adds a new child, whose parent is this instance, with the given `name`. /// @@ -19,147 +19,63 @@ pub trait Progress: Send + Sync { /// This will make the child progress to appear contained in the parent progress, and it can be identified /// using `id`. fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress; +} - /// Initialize the Item for receiving progress information. - /// - /// If `max` is `Some(…)`, it will be treated as upper bound. When progress is [set(…)](./struct.Item.html#method.set) - /// it should not exceed the given maximum. - /// If `max` is `None`, the progress is unbounded. Use this if the amount of work cannot accurately - /// be determined in advance. - /// - /// If `unit` is `Some(…)`, it is used for display purposes only. See `prodash::Unit` for more information. - /// - /// If both `unit` and `max` are `None`, the item will be reset to be equivalent to 'uninitialized'. - /// - /// If this method is never called, this `Progress` instance will serve as organizational unit, useful to add more structure - /// to the progress tree (e.g. a headline). - /// - /// **Note** that this method can be called multiple times, changing the bounded-ness and unit at will. - fn init(&mut self, max: Option<progress::Step>, unit: Option<Unit>); - +/// A thread-safe read-only counter, with unknown limits. +pub trait Count { /// Set the current progress to the given `step`. The cost of this call is negligible, /// making manual throttling *not* necessary. /// /// **Note**: that this call has no effect unless `init(…)` was called before. - fn set(&mut self, step: progress::Step); - - /// Returns the (cloned) unit associated with this Progress - fn unit(&self) -> Option<Unit> { - None - } - - /// Returns the maximum about of items we expect, as provided with the `init(…)` call - fn max(&self) -> Option<progress::Step> { - None - } - - /// Set the maximum value to `max` and return the old maximum value. - fn set_max(&mut self, _max: Option<progress::Step>) -> Option<progress::Step> { - None - } + fn set(&self, step: progress::Step); /// Returns the current step, as controlled by `inc*(…)` calls fn step(&self) -> progress::Step; /// Increment the current progress to the given `step`. /// The cost of this call is negligible, making manual throttling *not* necessary. - fn inc_by(&mut self, step: progress::Step); + fn inc_by(&self, step: progress::Step); /// Increment the current progress to the given 1. The cost of this call is negligible, /// making manual throttling *not* necessary. - fn inc(&mut self) { + fn inc(&self) { self.inc_by(1) } - /// Set the name of the instance, altering the value given when crating it with `add_child(…)` - /// The progress is allowed to discard it. - fn set_name(&mut self, name: impl Into<String>); - - /// Get the name of the instance as given when creating it with `add_child(…)` - /// The progress is allowed to not be named, thus there is no guarantee that a previously set names 'sticks'. - fn name(&self) -> Option<String>; - - /// Get a stable identifier for the progress instance. - /// Note that it could be [unknown][crate::progress::UNKNOWN]. - fn id(&self) -> Id; - - /// Create a `message` of the given `level` and store it with the progress tree. - /// - /// Use this to provide additional,human-readable information about the progress - /// made, including indicating success or failure. - fn message(&self, level: MessageLevel, message: impl Into<String>); - - /// If available, return an atomic counter for direct access to the underlying state. + /// Return an atomic counter for direct access to the underlying state. /// /// This is useful if multiple threads want to access the same progress, without the need /// for provide each their own progress and aggregating the result. - fn counter(&self) -> Option<StepShared> { - None - } - - /// Create a message providing additional information about the progress thus far. - fn info(&self, message: impl Into<String>) { - self.message(MessageLevel::Info, message) - } - /// Create a message indicating the task is done successfully - fn done(&self, message: impl Into<String>) { - self.message(MessageLevel::Success, message) - } - /// Create a message indicating the task failed - fn fail(&self, message: impl Into<String>) { - self.message(MessageLevel::Failure, message) - } - /// A shorthand to print throughput information - fn show_throughput(&self, start: Instant) { - let step = self.step(); - match self.unit() { - Some(unit) => self.show_throughput_with(start, step, unit, MessageLevel::Info), - None => { - let elapsed = start.elapsed().as_secs_f32(); - let steps_per_second = (step as f32 / elapsed) as progress::Step; - self.info(format!( - "done {} items in {:.02}s ({} items/s)", - step, elapsed, steps_per_second - )) - } - }; - } + fn counter(&self) -> StepShared; +} - /// A shorthand to print throughput information, with the given step and unit, and message level. - fn show_throughput_with(&self, start: Instant, step: progress::Step, unit: Unit, level: MessageLevel) { - use std::fmt::Write; - let elapsed = start.elapsed().as_secs_f32(); - let steps_per_second = (step as f32 / elapsed) as progress::Step; - let mut buf = String::with_capacity(128); - let unit = unit.as_display_value(); - let push_unit = |buf: &mut String| { - buf.push(' '); - let len_before_unit = buf.len(); - unit.display_unit(buf, step).ok(); - if buf.len() == len_before_unit { - buf.pop(); - } - }; +/// An object-safe trait for describing hierarchical progress. +/// +/// This will be automatically implemented for any type that implements +/// [`NestedProgress`]. +pub trait DynNestedProgress: Progress + impls::Sealed { + /// See [`NestedProgress::add_child`] + fn add_child(&mut self, name: String) -> BoxedDynNestedProgress; + + /// See [`NestedProgress::add_child_with_id`] + fn add_child_with_id(&mut self, name: String, id: Id) -> BoxedDynNestedProgress; +} - buf.push_str("done "); - unit.display_current_value(&mut buf, step, None).ok(); - push_unit(&mut buf); +/// An opaque type for storing [`DynNestedProgress`]. +pub struct BoxedDynNestedProgress(Box<dyn DynNestedProgress>); - buf.write_fmt(format_args!(" in {:.02}s (", elapsed)).ok(); - unit.display_current_value(&mut buf, steps_per_second, None).ok(); - push_unit(&mut buf); - buf.push_str("/s)"); +/// An owned version of [`Progress`] which can itself implement said trait. +pub type BoxedProgress = Box<dyn Progress>; - self.message(level, buf); - } -} +/// A bridge type that implements [`NestedProgress`] for any type that implements [`DynNestedProgress`]. +pub struct DynNestedProgressToNestedProgress<T: ?Sized>(pub T); /// A trait for describing non-hierarchical progress. /// /// It differs by not being able to add child progress dynamically, but in turn is object safe. It's recommended to /// use this trait whenever there is no need to add child progress, at the leaf of a computation. // NOTE: keep this in-sync with `Progress`. -pub trait RawProgress: Send + Sync { +pub trait Progress: Count + Send + Sync { /// Initialize the Item for receiving progress information. /// /// If `max` is `Some(…)`, it will be treated as upper bound. When progress is [set(…)](./struct.Item.html#method.set) @@ -177,12 +93,6 @@ pub trait RawProgress: Send + Sync { /// **Note** that this method can be called multiple times, changing the bounded-ness and unit at will. fn init(&mut self, max: Option<progress::Step>, unit: Option<Unit>); - /// Set the current progress to the given `step`. The cost of this call is negligible, - /// making manual throttling *not* necessary. - /// - /// **Note**: that this call has no effect unless `init(…)` was called before. - fn set(&mut self, step: progress::Step); - /// Returns the (cloned) unit associated with this Progress fn unit(&self) -> Option<Unit> { None @@ -198,19 +108,6 @@ pub trait RawProgress: Send + Sync { None } - /// Returns the current step, as controlled by `inc*(…)` calls - fn step(&self) -> progress::Step; - - /// Increment the current progress to the given `step`. - /// The cost of this call is negligible, making manual throttling *not* necessary. - fn inc_by(&mut self, step: progress::Step); - - /// Increment the current progress to the given 1. The cost of this call is negligible, - /// making manual throttling *not* necessary. - fn inc(&mut self) { - self.inc_by(1) - } - /// Set the name of the instance, altering the value given when crating it with `add_child(…)` /// The progress is allowed to discard it. fn set_name(&mut self, name: String); @@ -229,14 +126,6 @@ pub trait RawProgress: Send + Sync { /// made, including indicating success or failure. fn message(&self, level: MessageLevel, message: String); - /// If available, return an atomic counter for direct access to the underlying state. - /// - /// This is useful if multiple threads want to access the same progress, without the need - /// for provide each their own progress and aggregating the result. - fn counter(&self) -> Option<StepShared> { - None - } - /// Create a message providing additional information about the progress thus far. fn info(&self, message: String) { self.message(MessageLevel::Info, message) @@ -345,95 +234,127 @@ mod impls { time::Instant, }; - use crate::traits::RawProgress; + use crate::traits::{BoxedProgress, Progress}; use crate::{ messages::MessageLevel, progress::{Id, Step, StepShared}, - Progress, Unit, + BoxedDynNestedProgress, Count, DynNestedProgress, DynNestedProgressToNestedProgress, NestedProgress, Unit, }; - impl<T> RawProgress for T + pub trait Sealed {} + + impl<'a, T> Count for &'a T where - T: Progress, + T: Count + ?Sized, { - fn init(&mut self, max: Option<Step>, unit: Option<Unit>) { - <T as Progress>::init(self, max, unit) + fn set(&self, step: Step) { + (*self).set(step) } - fn set(&mut self, step: Step) { - <T as Progress>::set(self, step) + fn step(&self) -> Step { + (*self).step() } - fn unit(&self) -> Option<Unit> { - <T as Progress>::unit(self) + fn inc_by(&self, step: Step) { + (*self).inc_by(step) } - fn max(&self) -> Option<Step> { - <T as Progress>::max(self) + fn inc(&self) { + (*self).inc() } - fn set_max(&mut self, max: Option<Step>) -> Option<Step> { - <T as Progress>::set_max(self, max) + fn counter(&self) -> StepShared { + (*self).counter() + } + } + + impl<'a, T> Count for &'a mut T + where + T: Count + ?Sized, + { + fn set(&self, step: Step) { + self.deref().set(step) } fn step(&self) -> Step { - <T as Progress>::step(self) + self.deref().step() } - fn inc_by(&mut self, step: Step) { - <T as Progress>::inc_by(self, step) + fn inc_by(&self, step: Step) { + self.deref().inc_by(step) } - fn inc(&mut self) { - <T as Progress>::inc(self) + fn inc(&self) { + self.deref().inc() + } + + fn counter(&self) -> StepShared { + self.deref().counter() + } + } + + impl<'a, T> Progress for &'a mut T + where + T: Progress + ?Sized, + { + fn init(&mut self, max: Option<Step>, unit: Option<Unit>) { + self.deref_mut().init(max, unit) + } + + fn unit(&self) -> Option<Unit> { + self.deref().unit() + } + + fn max(&self) -> Option<Step> { + self.deref().max() + } + + fn set_max(&mut self, max: Option<Step>) -> Option<Step> { + self.deref_mut().set_max(max) } fn set_name(&mut self, name: String) { - <T as Progress>::set_name(self, name) + self.deref_mut().set_name(name) } fn name(&self) -> Option<String> { - <T as Progress>::name(self) + self.deref().name() } fn id(&self) -> Id { - <T as Progress>::id(self) + self.deref().id() } fn message(&self, level: MessageLevel, message: String) { - <T as Progress>::message(self, level, message) - } - - fn counter(&self) -> Option<StepShared> { - <T as Progress>::counter(self) + self.deref().message(level, message) } fn info(&self, message: String) { - <T as Progress>::info(self, message) + self.deref().info(message) } fn done(&self, message: String) { - <T as Progress>::done(self, message) + self.deref().done(message) } fn fail(&self, message: String) { - <T as Progress>::fail(self, message) + self.deref().fail(message) } fn show_throughput(&self, start: Instant) { - <T as Progress>::show_throughput(self, start) + self.deref().show_throughput(start) } fn show_throughput_with(&self, start: Instant, step: Step, unit: Unit, level: MessageLevel) { - <T as Progress>::show_throughput_with(self, start, step, unit, level) + self.deref().show_throughput_with(start, step, unit, level) } } - impl<'a, T> Progress for &'a mut T + impl<'a, T> NestedProgress for &'a mut T where - T: Progress, + T: NestedProgress + ?Sized, { - type SubProgress = <T as Progress>::SubProgress; + type SubProgress = T::SubProgress; fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { self.deref_mut().add_child(name) @@ -442,40 +363,91 @@ mod impls { fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { self.deref_mut().add_child_with_id(name, id) } + } - fn init(&mut self, max: Option<Step>, unit: Option<Unit>) { - self.deref_mut().init(max, unit) + impl<T> Sealed for T where T: NestedProgress + ?Sized {} + + impl<T, SubP> DynNestedProgress for T + where + T: NestedProgress<SubProgress = SubP> + ?Sized, + SubP: NestedProgress + 'static, + { + fn add_child(&mut self, name: String) -> BoxedDynNestedProgress { + BoxedDynNestedProgress::new(self.add_child(name)) + } + + fn add_child_with_id(&mut self, name: String, id: Id) -> BoxedDynNestedProgress { + BoxedDynNestedProgress::new(self.add_child_with_id(name, id)) } + } - fn set(&mut self, step: Step) { - self.deref_mut().set(step) + impl BoxedDynNestedProgress { + /// Create new instance from a `DynProgress` implementation. + pub fn new(progress: impl DynNestedProgress + 'static) -> Self { + Self(Box::new(progress)) + } + } + + impl Progress for BoxedDynNestedProgress { + fn init(&mut self, max: Option<Step>, unit: Option<Unit>) { + self.0.init(max, unit) } fn unit(&self) -> Option<Unit> { - self.deref().unit() + self.0.unit() } fn max(&self) -> Option<Step> { - self.deref().max() + self.0.max() } fn set_max(&mut self, max: Option<Step>) -> Option<Step> { - self.deref_mut().set_max(max) + self.0.set_max(max) } - fn step(&self) -> Step { - self.deref().step() + fn set_name(&mut self, name: String) { + self.0.set_name(name) + } + + fn name(&self) -> Option<String> { + self.0.name() } - fn inc_by(&mut self, step: Step) { - self.deref_mut().inc_by(step) + fn id(&self) -> Id { + self.0.id() + } + + fn message(&self, level: MessageLevel, message: String) { + self.0.message(level, message) + } + + fn show_throughput(&self, start: Instant) { + self.0.show_throughput(start) + } + + fn show_throughput_with(&self, start: Instant, step: Step, unit: Unit, level: MessageLevel) { + self.0.show_throughput_with(start, step, unit, level) + } + } + + impl Progress for BoxedProgress { + fn init(&mut self, max: Option<Step>, unit: Option<Unit>) { + self.deref_mut().init(max, unit) } - fn inc(&mut self) { - self.deref_mut().inc() + fn unit(&self) -> Option<Unit> { + self.deref().unit() } - fn set_name(&mut self, name: impl Into<String>) { + fn max(&self) -> Option<Step> { + self.deref().max() + } + + fn set_max(&mut self, max: Option<Step>) -> Option<Step> { + self.deref_mut().set_max(max) + } + + fn set_name(&mut self, name: String) { self.deref_mut().set_name(name) } @@ -487,32 +459,157 @@ mod impls { self.deref().id() } - fn message(&self, level: MessageLevel, message: impl Into<String>) { + fn message(&self, level: MessageLevel, message: String) { self.deref().message(level, message) } - fn counter(&self) -> Option<StepShared> { + fn show_throughput(&self, start: Instant) { + self.deref().show_throughput(start) + } + + fn show_throughput_with(&self, start: Instant, step: Step, unit: Unit, level: MessageLevel) { + self.deref().show_throughput_with(start, step, unit, level) + } + } + + impl Count for BoxedDynNestedProgress { + fn set(&self, step: Step) { + self.0.set(step) + } + + fn step(&self) -> Step { + self.0.step() + } + + fn inc_by(&self, step: Step) { + self.0.inc_by(step) + } + + fn inc(&self) { + self.0.inc() + } + + fn counter(&self) -> StepShared { + self.0.counter() + } + } + + impl Count for BoxedProgress { + fn set(&self, step: Step) { + self.deref().set(step) + } + + fn step(&self) -> Step { + self.deref().step() + } + + fn inc_by(&self, step: Step) { + self.deref().inc_by(step) + } + + fn inc(&self) { + self.deref().inc() + } + + fn counter(&self) -> StepShared { self.deref().counter() } + } - fn info(&self, message: impl Into<String>) { - self.deref().info(message) + impl NestedProgress for BoxedDynNestedProgress { + type SubProgress = Self; + + fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { + self.0.add_child(name.into()) } - fn done(&self, message: impl Into<String>) { - self.deref().done(message) + fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { + self.0.add_child_with_id(name.into(), id) } + } - fn fail(&self, message: impl Into<String>) { - self.deref().fail(message) + impl<T> Progress for DynNestedProgressToNestedProgress<T> + where + T: ?Sized + Progress, + { + fn init(&mut self, max: Option<Step>, unit: Option<Unit>) { + self.0.init(max, unit) + } + + fn unit(&self) -> Option<Unit> { + self.0.unit() + } + + fn max(&self) -> Option<Step> { + self.0.max() + } + + fn set_max(&mut self, max: Option<Step>) -> Option<Step> { + self.0.set_max(max) + } + + fn set_name(&mut self, name: String) { + self.0.set_name(name) + } + + fn name(&self) -> Option<String> { + self.0.name() + } + + fn id(&self) -> Id { + self.0.id() + } + + fn message(&self, level: MessageLevel, message: String) { + self.0.message(level, message) } fn show_throughput(&self, start: Instant) { - self.deref().show_throughput(start) + self.0.show_throughput(start) } fn show_throughput_with(&self, start: Instant, step: Step, unit: Unit, level: MessageLevel) { - self.deref().show_throughput_with(start, step, unit, level) + self.0.show_throughput_with(start, step, unit, level) + } + } + + impl<T> Count for DynNestedProgressToNestedProgress<T> + where + T: ?Sized + Count, + { + fn set(&self, step: Step) { + self.0.set(step) + } + + fn step(&self) -> Step { + self.0.step() + } + + fn inc_by(&self, step: Step) { + self.0.inc_by(step) + } + + fn inc(&self) { + self.0.inc() + } + + fn counter(&self) -> StepShared { + self.0.counter() + } + } + + impl<T> NestedProgress for DynNestedProgressToNestedProgress<T> + where + T: DynNestedProgress + ?Sized, + { + type SubProgress = BoxedDynNestedProgress; + + fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { + self.0.add_child(name.into()) + } + + fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { + self.0.add_child_with_id(name.into(), id) } } } diff --git a/vendor/prodash/src/tree/item.rs b/vendor/prodash/src/tree/item.rs index 17dbb64da..d434a347e 100644 --- a/vendor/prodash/src/tree/item.rs +++ b/vendor/prodash/src/tree/item.rs @@ -46,7 +46,7 @@ impl Item { /// to the progress tree. /// /// **Note** that this method can be called multiple times, changing the bounded-ness and unit at will. - pub fn init(&mut self, max: Option<usize>, unit: Option<Unit>) { + pub fn init(&self, max: Option<usize>, unit: Option<Unit>) { #[cfg(feature = "progress-tree-hp-hashmap")] { if let Some(mut r) = self.tree.get_mut(&self.key) { @@ -73,7 +73,7 @@ impl Item { } } - fn alter_progress(&mut self, f: impl FnMut(&mut Value)) { + fn alter_progress(&self, f: impl FnMut(&mut Value)) { #[cfg(feature = "progress-tree-hp-hashmap")] { if let Some(mut r) = self.tree.get_mut(&self.key) { @@ -94,7 +94,7 @@ impl Item { } /// Set the name of this task's progress to the given `name`. - pub fn set_name(&mut self, name: impl Into<String>) { + pub fn set_name(&self, name: impl Into<String>) { #[cfg(feature = "progress-tree-hp-hashmap")] { if let Some(mut r) = self.tree.get_mut(&self.key) { @@ -158,7 +158,7 @@ impl Item { } /// Set the maximum value to `max` and return the old maximum value. - pub fn set_max(&mut self, max: Option<Step>) -> Option<Step> { + pub fn set_max(&self, max: Option<Step>) -> Option<Step> { #[cfg(feature = "progress-tree-hp-hashmap")] { self.tree @@ -166,7 +166,7 @@ impl Item { .value_mut() .progress .as_mut() - .and_then(|mut p| { + .and_then(|p| { let prev = p.done_at; p.done_at = max; prev @@ -176,7 +176,7 @@ impl Item { { self.tree .get_mut(&self.key, |v| { - v.progress.as_mut().and_then(|mut p| { + v.progress.as_mut().and_then(|p| { let prev = p.done_at; p.done_at = max; prev @@ -205,22 +205,22 @@ impl Item { /// Set the current progress to the given `step`. /// /// **Note**: that this call has no effect unless `init(…)` was called before. - pub fn set(&mut self, step: Step) { + pub fn set(&self, step: Step) { self.value.store(step, Ordering::SeqCst); } /// Increment the current progress by the given `step`. /// /// **Note**: that this call has no effect unless `init(…)` was called before. - pub fn inc_by(&mut self, step: Step) { - self.value.fetch_add(step, Ordering::SeqCst); + pub fn inc_by(&self, step: Step) { + self.value.fetch_add(step, Ordering::Relaxed); } /// Increment the current progress by one. /// /// **Note**: that this call has no effect unless `init(…)` was called before. - pub fn inc(&mut self) { - self.value.fetch_add(1, Ordering::SeqCst); + pub fn inc(&self) { + self.value.fetch_add(1, Ordering::Relaxed); } /// Call to indicate that progress cannot be indicated, and that the task cannot be interrupted. @@ -231,7 +231,7 @@ impl Item { /// make progress again. /// /// The halted-state is undone next time [`tree::Item::running(…)`][Item::running()] is called. - pub fn blocked(&mut self, reason: &'static str, eta: Option<SystemTime>) { + pub fn blocked(&self, reason: &'static str, eta: Option<SystemTime>) { self.alter_progress(|p| p.state = State::Blocked(reason, eta)); } @@ -243,13 +243,13 @@ impl Item { /// make progress again. /// /// The halted-state is undone next time [`tree::Item::running(…)`][Item::running()] is called. - pub fn halted(&mut self, reason: &'static str, eta: Option<SystemTime>) { + pub fn halted(&self, reason: &'static str, eta: Option<SystemTime>) { self.alter_progress(|p| p.state = State::Halted(reason, eta)); } /// Call to indicate that progress is back in running state, which should be called after the reason for /// calling `blocked()` or `halted()` has passed. - pub fn running(&mut self) { + pub fn running(&self) { self.alter_progress(|p| p.state = State::Running); } @@ -345,23 +345,27 @@ impl Item { } } -impl crate::Progress for Item { - type SubProgress = Item; +impl crate::Count for Item { + fn set(&self, step: usize) { + Item::set(self, step) + } - fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress { - Item::add_child(self, name) + fn step(&self) -> usize { + Item::step(self).unwrap_or(0) } - fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress { - Item::add_child_with_id(self, name, id) + fn inc_by(&self, step: usize) { + self.inc_by(step) } - fn init(&mut self, max: Option<Step>, unit: Option<Unit>) { - Item::init(self, max, unit) + fn counter(&self) -> StepShared { + Arc::clone(&self.value) } +} - fn set(&mut self, step: usize) { - Item::set(self, step) +impl crate::Progress for Item { + fn init(&mut self, max: Option<Step>, unit: Option<Unit>) { + Item::init(self, max, unit) } fn unit(&self) -> Option<Unit> { @@ -376,15 +380,7 @@ impl crate::Progress for Item { Item::set_max(self, max) } - fn step(&self) -> usize { - Item::step(self).unwrap_or(0) - } - - fn inc_by(&mut self, step: usize) { - self.inc_by(step) - } - - fn set_name(&mut self, name: impl Into<String>) { + fn set_name(&mut self, name: String) { Item::set_name(self, name) } @@ -396,11 +392,19 @@ impl crate::Progress for Item { Item::id(self) } - fn message(&self, level: MessageLevel, message: impl Into<String>) { + fn message(&self, level: MessageLevel, message: String) { Item::message(self, level, message) } +} + +impl crate::NestedProgress for Item { + type SubProgress = Item; - fn counter(&self) -> Option<StepShared> { - Some(Arc::clone(&self.value)) + fn add_child(&mut self, name: impl Into<String>) -> Self { + Item::add_child(self, name) + } + + fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self { + Item::add_child_with_id(self, name, id) } } |