arkham/src/tasks.rs

66 lines
1.5 KiB
Rust
Raw Normal View History

2021-06-19 07:20:29 +00:00
use console::style;
use indicatif::{HumanDuration, MultiProgress, ProgressBar, ProgressStyle};
use std::{
sync::{Arc, Mutex},
time::Instant,
};
#[derive(Clone)]
pub struct TaskGroup {
mp: Arc<MultiProgress>,
}
impl TaskGroup {
pub fn new() -> Self {
Self {
mp: Arc::new(MultiProgress::new()),
}
}
pub fn start_task(&self, desc: &str) -> Task {
let pb = self.mp.add(ProgressBar::new(1));
let spinner_style = ProgressStyle::default_spinner()
.tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈ ")
.template("{prefix:.bold.dim} {spinner} {wide_msg}");
pb.set_style(spinner_style);
Task::new(TaskState {
pb,
desc: desc.into(),
started_at: Instant::now(),
})
}
pub fn join(&self) {
self.mp.join().unwrap();
}
}
#[derive(Clone)]
pub struct Task(Arc<Mutex<TaskState>>);
impl Task {
pub fn new(state: TaskState) -> Self {
Self(Arc::new(Mutex::new(state)))
}
pub fn tick(&self) {
let state = self.0.lock().unwrap();
state.pb.set_message(&format!(
"{} [{}]",
state.desc,
style(HumanDuration(state.started_at.elapsed())).yellow()
));
state.pb.tick();
}
pub fn complete(&self) {
self.0.lock().unwrap().pb.finish_with_message("OK");
}
}
pub struct TaskState {
pb: ProgressBar,
desc: String,
started_at: Instant,
}