use std::sync::OnceLock;
use crate::console::{Console, Renderable};
use crate::progress::{ProgressColumn, Task};
use crate::progress_bar::ProgressBar;
use crate::text::Text;
pub struct BarColumn {
pub bar_width: Option<usize>,
pub style: String,
pub complete_style: String,
pub finished_style: String,
pub pulse_style: String,
console_cache: OnceLock<Console>,
}
impl std::fmt::Debug for BarColumn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BarColumn")
.field("bar_width", &self.bar_width)
.field("style", &self.style)
.field("complete_style", &self.complete_style)
.field("finished_style", &self.finished_style)
.field("pulse_style", &self.pulse_style)
.finish()
}
}
impl Clone for BarColumn {
fn clone(&self) -> Self {
BarColumn {
bar_width: self.bar_width,
style: self.style.clone(),
complete_style: self.complete_style.clone(),
finished_style: self.finished_style.clone(),
pulse_style: self.pulse_style.clone(),
console_cache: OnceLock::new(),
}
}
}
impl BarColumn {
pub fn new() -> Self {
BarColumn {
bar_width: Some(40),
style: "bar.back".to_string(),
complete_style: "bar.complete".to_string(),
finished_style: "bar.finished".to_string(),
pulse_style: "bar.pulse".to_string(),
console_cache: OnceLock::new(),
}
}
#[must_use]
pub fn with_bar_width(mut self, width: Option<usize>) -> Self {
self.console_cache = OnceLock::new();
self.bar_width = width;
self
}
fn console(&self) -> &Console {
self.console_cache.get_or_init(|| {
Console::builder()
.width(self.bar_width.unwrap_or(40))
.color_system("truecolor")
.build()
})
}
}
impl Default for BarColumn {
fn default() -> Self {
Self::new()
}
}
impl ProgressColumn for BarColumn {
fn render(&self, task: &Task) -> Text {
let pulse = !task.started();
let bar = ProgressBar::new()
.with_total(task.total)
.with_completed(task.completed)
.with_width(self.bar_width)
.with_style(&self.style)
.with_complete_style(&self.complete_style)
.with_finished_style(&self.finished_style)
.with_pulse_style(&self.pulse_style)
.with_pulse(pulse);
let console = self.console();
let opts = console.options();
let segments = bar.gilt_console(console, &opts);
let mut text = Text::empty();
for seg in &segments {
text.append_str(&seg.text, seg.style().cloned());
}
text.end = String::new();
text
}
}