deno.land / x / deno@v1.28.2 / cli / progress_bar.rs
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
use crate::colors;use deno_core::parking_lot::Mutex;use indexmap::IndexSet;use std::sync::Arc;use std::time::Duration;
#[derive(Clone, Debug, Default)]pub struct ProgressBar(Arc<Mutex<ProgressBarInner>>);
#[derive(Debug)]struct ProgressBarInner { pb: Option<indicatif::ProgressBar>, is_tty: bool, in_flight: IndexSet<String>,}
impl Default for ProgressBarInner { fn default() -> Self { Self { pb: None, is_tty: colors::is_tty(), in_flight: IndexSet::default(), } }}
impl ProgressBarInner { fn get_or_create_pb(&mut self) -> indicatif::ProgressBar { if let Some(pb) = self.pb.as_ref() { return pb.clone(); }
let pb = indicatif::ProgressBar::new_spinner(); pb.enable_steady_tick(Duration::from_millis(120)); pb.set_prefix("Download"); pb.set_style( indicatif::ProgressStyle::with_template( "{prefix:.green} {spinner:.green} {msg}", ) .unwrap() .tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]), ); self.pb = Some(pb); self.pb.as_ref().unwrap().clone() }
fn add_in_flight(&mut self, msg: &str) { if self.in_flight.contains(msg) { return; }
self.in_flight.insert(msg.to_string()); }
/// Returns if removed "in-flight" was last entry and progress /// bar needs to be updated. fn remove_in_flight(&mut self, msg: &str) -> bool { if !self.in_flight.contains(msg) { return false; }
let mut is_last = false; if let Some(last) = self.in_flight.last() { is_last = last == msg; } self.in_flight.remove(msg); is_last }
fn update_progress_bar(&mut self) { let pb = self.get_or_create_pb(); if let Some(msg) = self.in_flight.last() { pb.set_message(msg.clone()); } }}
pub struct UpdateGuard { pb: ProgressBar, msg: String, noop: bool,}
impl Drop for UpdateGuard { fn drop(&mut self) { if self.noop { return; }
let mut inner = self.pb.0.lock(); if inner.remove_in_flight(&self.msg) { inner.update_progress_bar(); } }}
impl ProgressBar { pub fn update(&self, msg: &str) -> UpdateGuard { let mut guard = UpdateGuard { pb: self.clone(), msg: msg.to_string(), noop: false, }; let mut inner = self.0.lock();
// If we're not running in TTY we're just gonna fallback // to using logger crate. if !inner.is_tty { log::log!(log::Level::Info, "{} {}", colors::green("Download"), msg); guard.noop = true; return guard; }
inner.add_in_flight(msg); inner.update_progress_bar(); guard }
pub fn clear(&self) { let mut inner = self.0.lock();
if let Some(pb) = inner.pb.as_ref() { pb.finish_and_clear(); inner.pb = None; } }
pub fn clear_guard(&self) -> ClearGuard { ClearGuard { pb: self.clone() } }}
pub struct ClearGuard { pb: ProgressBar,}
impl Drop for ClearGuard { fn drop(&mut self) { self.pb.clear(); }}
Version Info