mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-06 19:45:29 +00:00
101 lines
2.9 KiB
Rust
101 lines
2.9 KiB
Rust
//! Module that provides functions to display progress bars for compressing and decompressing files.
|
|
use std::{
|
|
fmt::Arguments,
|
|
io::{Read, Stderr, Write},
|
|
};
|
|
|
|
use indicatif::{ProgressBar, ProgressBarIter, ProgressStyle};
|
|
|
|
use crate::utils::colors::{ORANGE, RESET, YELLOW};
|
|
|
|
/// Draw a ProgressBar using a function that checks periodically for the progress
|
|
pub struct Progress {
|
|
bar: ProgressBar,
|
|
}
|
|
|
|
pub trait OutputLine {
|
|
fn output_line(&mut self, args: Arguments);
|
|
fn output_line_info(&mut self, args: Arguments);
|
|
fn output_line_warning(&mut self, args: Arguments);
|
|
}
|
|
|
|
impl OutputLine for Progress {
|
|
fn output_line(&mut self, args: Arguments) {
|
|
self.bar.set_message(args.to_string());
|
|
}
|
|
|
|
fn output_line_info(&mut self, args: Arguments) {
|
|
self.bar.set_message(format!("{}[INFO]{} {args}", *YELLOW, *RESET));
|
|
}
|
|
|
|
fn output_line_warning(&mut self, args: Arguments) {
|
|
self.bar.println(format!("{}[WARNING]{} {args}", *ORANGE, *RESET));
|
|
}
|
|
}
|
|
|
|
impl OutputLine for Stderr {
|
|
fn output_line(&mut self, args: Arguments) {
|
|
self.write_fmt(args).unwrap();
|
|
}
|
|
|
|
fn output_line_info(&mut self, args: Arguments) {
|
|
write!(self, "{}[INFO]{} ", *YELLOW, *RESET).unwrap();
|
|
self.write_fmt(args).unwrap();
|
|
self.write_all(b"\n").unwrap();
|
|
}
|
|
|
|
fn output_line_warning(&mut self, args: Arguments) {
|
|
write!(self, "{}[WARNING]{}", *ORANGE, *RESET).unwrap();
|
|
self.write_fmt(args).unwrap();
|
|
self.write_all(b"\n").unwrap();
|
|
}
|
|
}
|
|
|
|
impl<T: OutputLine + ?Sized> OutputLine for &mut T {
|
|
fn output_line(&mut self, args: Arguments) {
|
|
(*self).output_line(args)
|
|
}
|
|
|
|
fn output_line_info(&mut self, args: Arguments) {
|
|
(*self).output_line_info(args);
|
|
}
|
|
|
|
fn output_line_warning(&mut self, args: Arguments) {
|
|
(*self).output_line_warning(args);
|
|
}
|
|
}
|
|
|
|
impl Progress {
|
|
pub(crate) fn new(total_input_size: u64, precise: bool, position_updates: bool) -> Self {
|
|
let template = {
|
|
let mut t = String::new();
|
|
t += "{wide_msg} [{elapsed_precise}] ";
|
|
if precise && position_updates {
|
|
t += "[{bar:.cyan/blue}] ";
|
|
} else {
|
|
t += "{spinner:.green} ";
|
|
}
|
|
if position_updates {
|
|
t += "{bytes}/ ";
|
|
}
|
|
if precise {
|
|
t += "{total_bytes} ";
|
|
}
|
|
t += "({bytes_per_sec}, {eta}) {path}";
|
|
t
|
|
};
|
|
let bar = ProgressBar::new(total_input_size)
|
|
.with_style(ProgressStyle::with_template(&template).unwrap().progress_chars("#>-"));
|
|
|
|
Progress { bar }
|
|
}
|
|
|
|
pub(crate) fn wrap_read<R: Read>(&self, read: R) -> ProgressBarIter<R> {
|
|
self.bar.wrap_read(read)
|
|
}
|
|
|
|
pub(crate) fn wrap_write<W: Write>(&self, write: W) -> ProgressBarIter<W> {
|
|
self.bar.wrap_write(write)
|
|
}
|
|
}
|