While this crate only has limited functionality for displaying progress bars, in the future it will be extended to support user input, localization and more.
ABPFWGKH24JK7TLAGDVENTA5VSVRANPBVRD555WCQMNW56BL7SZQC
DVBSW7SICQMTYIC4NOLA3CBRU5OWPAWX3MYEOZ7UWXF3IJLLJDYQC
JMOHVR5EL27IRLXO66W52DA4K33L467O5J5DRX2ARZTFM6JRHDVQC
STG7MO5MLMKFJYJQDAXL6YSUJE2BTXOMWUQHXBWFHDFJNNJRP5AQC
EJ7TFFOWLM5EXYX57NJZZX3NLPBLLMRX7CGJYC75DJZ5LYXOQPJAC
SXEYMYF7P4RZMZ46WPL4IZUTSQ2ATBWYZX7QNVMS3SGOYXYOHAGQC
TNN56XYKX4QRHA4FWCF5F3JVG52FIAC76EEYYANDKEE4IAWQKPEQC
ENWJBQGQUL3KLYPVGYP2ZSDB5ZUXLTY4W6NCHUA6VTHRRNPRUDHAC
]
[[package]]
name = "indicatif"
version = "0.17.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057"
dependencies = [
"console",
"instant",
"number_prefix",
"portable-atomic",
"unicode-segmentation",
"unicode-width",
use std::time::Duration;
use indicatif::MultiProgress;
use lazy_static::lazy_static;
use indicatif::ProgressStyle;
lazy_static! {
static ref MULTI_PROGRESS: MultiProgress = MultiProgress::new();
}
pub const DOWNLOAD_MESSAGE: &str = "Downloading changes";
pub const APPLY_MESSAGE: &str = "Applying changes";
pub const UPLOAD_MESSAGE: &str = "Uploading changes";
pub const COMPLETE_MESSAGE: &str = "Completing changes";
pub const OUTPUT_MESSAGE: &str = "Outputting repository";
#[derive(Clone, Debug)]
pub struct ProgressBar(Option<indicatif::ProgressBar>);
impl Drop for ProgressBar {
fn drop(&mut self) {
// Make sure the progress bar doesn't disappear after completion
if let Some(progress_bar) = &self.0 {
progress_bar.finish();
}
}
}
impl ProgressBar {
pub fn new(len: u64, message: &str) -> Result<Self, anyhow::Error> {
let style =
ProgressStyle::with_template("{msg:<20} [{bar:50}] {pos}/{len} [{elapsed_precise}]")?
.progress_chars("=> ");
let progress_bar = indicatif::ProgressBar::new(len)
.with_style(style)
.with_message(message.to_owned());
MULTI_PROGRESS.add(progress_bar.clone());
progress_bar.enable_steady_tick(Duration::from_millis(15));
Ok(Self(Some(progress_bar)))
}
pub fn hidden() -> Self {
Self(None)
}
pub fn inc(&self, delta: u64) {
if let Some(progress) = self.0.clone() {
progress.inc(delta);
}
}
pub fn inner(&self) -> Option<indicatif::ProgressBar> {
self.0.clone()
}
}
#[derive(Clone, Debug)]
pub struct Spinner(indicatif::ProgressBar);
impl Drop for Spinner {
fn drop(&mut self) {
// Make sure the spinner doesn't disappear after completion
self.finish().unwrap();
}
}
impl Spinner {
pub fn new(message: &str) -> Result<Self, anyhow::Error> {
let style = ProgressStyle::with_template("{msg}{spinner}")?
.tick_strings(&[". ", ".. ", "...", " "]);
let spinner = indicatif::ProgressBar::new_spinner()
.with_style(style)
.with_message(message.to_owned());
spinner.enable_steady_tick(Duration::from_millis(200));
MULTI_PROGRESS.add(spinner.clone());
Ok(Self(spinner))
}
pub fn finish(&self) -> Result<(), anyhow::Error> {
self.0.set_style(ProgressStyle::with_template("{msg}")?);
self.0
.finish_with_message(format!("{}... done!", self.0.message()));
Ok(())
}
}
pub mod progress;
[package]
name = "pijul-interaction"
description = "Human friendly input/output (progress bars, passwords etc) for contexts such as terminals or GUIs"
version = "0.0.1"
authors = ["Finchie"]
edition = "2021"
repository = "https://nest.pijul.com/pijul/pijul"
license = "GPL-2.0"
include = [ "Cargo.toml", "src" ]
[dependencies]
anyhow = { version = "1.0", features = ["backtrace"] }
indicatif = { version = "0.17", features = ["improved_unicode"] }
lazy_static = "1.4"