summaryrefslogtreecommitdiffstats
path: root/vendor/prodash/src/progress/log.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/prodash/src/progress/log.rs
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz
rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/prodash/src/progress/log.rs')
-rw-r--r--vendor/prodash/src/progress/log.rs151
1 files changed, 151 insertions, 0 deletions
diff --git a/vendor/prodash/src/progress/log.rs b/vendor/prodash/src/progress/log.rs
new file mode 100644
index 000000000..3410a5dc2
--- /dev/null
+++ b/vendor/prodash/src/progress/log.rs
@@ -0,0 +1,151 @@
+use std::{
+ sync::{
+ atomic::{AtomicBool, Ordering},
+ Arc,
+ },
+ time::Duration,
+};
+
+use crate::{
+ messages::MessageLevel,
+ progress::{Id, Step, StepShared},
+ Progress, Unit,
+};
+
+/// A [`Progress`] 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.
+pub struct Log {
+ name: String,
+ id: Id,
+ max: Option<usize>,
+ unit: Option<Unit>,
+ step: usize,
+ current_level: usize,
+ max_level: usize,
+ trigger: Arc<AtomicBool>,
+}
+
+const EMIT_LOG_EVERY_S: f32 = 0.5;
+const SEP: &str = "::";
+
+impl Log {
+ /// Create a new instance from `name` while displaying progress information only up to `max_level`.
+ pub fn new(name: impl Into<String>, max_level: Option<usize>) -> Self {
+ let trigger = Arc::new(AtomicBool::new(true));
+ std::thread::spawn({
+ let duration = Duration::from_secs_f32(EMIT_LOG_EVERY_S);
+ let trigger = Arc::downgrade(&trigger);
+ move || {
+ while let Some(t) = trigger.upgrade() {
+ t.store(true, Ordering::Relaxed);
+ std::thread::sleep(duration);
+ }
+ }
+ });
+ Log {
+ name: name.into(),
+ id: crate::progress::UNKNOWN,
+ current_level: 0,
+ max_level: max_level.unwrap_or(usize::MAX),
+ max: None,
+ step: 0,
+ 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;
+ if self.current_level > self.max_level {
+ return;
+ }
+ if self.trigger.swap(false, Ordering::Relaxed) {
+ match (self.max, &self.unit) {
+ (max, Some(unit)) => log::info!("{} → {}", self.name, unit.display(step, max, None)),
+ (Some(max), None) => log::info!("{} → {} / {}", self.name, step, max),
+ (None, None) => log::info!("{} → {}", self.name, step),
+ }
+ }
+ }
+
+ fn unit(&self) -> Option<Unit> {
+ self.unit.clone()
+ }
+
+ fn max(&self) -> Option<usize> {
+ self.max
+ }
+
+ fn set_max(&mut self, max: Option<Step>) -> Option<Step> {
+ let prev = self.max;
+ self.max = max;
+ 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();
+ self.name = self
+ .name
+ .split("::")
+ .next()
+ .map(|parent| format!("{}{}{}", parent.to_owned(), SEP, name))
+ .unwrap_or(name);
+ }
+
+ fn name(&self) -> Option<String> {
+ self.name.split(SEP).nth(1).map(ToOwned::to_owned)
+ }
+
+ fn id(&self) -> Id {
+ self.id
+ }
+
+ fn message(&mut self, level: MessageLevel, message: impl Into<String>) {
+ let message: String = message.into();
+ match level {
+ MessageLevel::Info => log::info!("ℹ{} → {}", self.name, message),
+ MessageLevel::Failure => log::error!("𐄂{} → {}", self.name, message),
+ MessageLevel::Success => log::info!("✓{} → {}", self.name, message),
+ }
+ }
+
+ fn counter(&self) -> Option<StepShared> {
+ None
+ }
+}