diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
commit | 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch) | |
tree | bdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/prodash/src/progress/log.rs | |
parent | Releasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff) | |
download | rustc-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.rs | 151 |
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 + } +} |