Skip to content

Commit

Permalink
make progress bar optional in non-terminal envs
Browse files Browse the repository at this point in the history
  • Loading branch information
itegulov committed Oct 21, 2024
1 parent 7c28964 commit 82c7a48
Showing 1 changed file with 45 additions and 12 deletions.
57 changes: 45 additions & 12 deletions zkstack_cli/crates/common/src/term/spinner.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
use std::time::Instant;
use std::{fmt::Display, io::IsTerminal, time::Instant};

use cliclack::{spinner, ProgressBar};

use crate::config::global_config;
use crate::{config::global_config, logger};

/// Spinner is a helper struct to show a spinner while some operation is running.
pub struct Spinner {
msg: String,
pb: ProgressBar,
output: SpinnerOutput,
time: Instant,
}

impl Spinner {
/// Create a new spinner with a message.
pub fn new(msg: &str) -> Self {
let pb = spinner();
pb.start(msg);
if global_config().verbose {
pb.stop(msg);
}
let output = if std::io::stdout().is_terminal() {
let pb = spinner();
pb.start(msg);
if global_config().verbose {
pb.stop(msg);
}
SpinnerOutput::Progress(pb)
} else {
logger::info(msg);
SpinnerOutput::Plain()
};
Spinner {
msg: msg.to_owned(),
pb,
output,
time: Instant::now(),
}
}

/// Manually finish the spinner.
pub fn finish(self) {
self.pb.stop(format!(
self.output.stop(format!(
"{} done in {} secs",
self.msg,
self.time.elapsed().as_secs_f64()
Expand All @@ -37,7 +43,7 @@ impl Spinner {

/// Interrupt the spinner with a failed message.
pub fn fail(self) {
self.pb.error(format!(
self.output.error(format!(
"{} failed in {} secs",
self.msg,
self.time.elapsed().as_secs_f64()
Expand All @@ -46,6 +52,33 @@ impl Spinner {

/// Freeze the spinner with current message.
pub fn freeze(self) {
self.pb.stop(self.msg);
self.output.stop(self.msg);
}
}

/// An abstraction that makes interactive progress bar optional in environments where virtual
/// terminal is not available.
///
/// Uses plain `logger::{info,error}` as the fallback.
///
/// See https://github.com/console-rs/indicatif/issues/530 for more details.
enum SpinnerOutput {
Progress(ProgressBar),
Plain(),
}

impl SpinnerOutput {
fn error(&self, msg: impl Display) {
match self {
SpinnerOutput::Progress(pb) => pb.error(msg),
SpinnerOutput::Plain() => logger::error(msg),
}
}

fn stop(self, msg: impl Display) {
match self {
SpinnerOutput::Progress(pb) => pb.stop(msg),
SpinnerOutput::Plain() => logger::info(msg),
}
}
}

0 comments on commit 82c7a48

Please sign in to comment.