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/traits.rs | |
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/traits.rs')
-rw-r--r-- | vendor/prodash/src/traits.rs | 495 |
1 files changed, 296 insertions, 199 deletions
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) } } } |