use crate::progress::{ProgressColumn, Task};
use crate::style::Style;
use crate::text::{JustifyMethod, Text};
#[derive(Debug, Clone)]
pub struct TextColumn {
pub text: String,
pub style: Option<Style>,
pub justify: JustifyMethod,
}
impl TextColumn {
pub fn new(text: &str) -> Self {
TextColumn {
text: text.to_string(),
style: None,
justify: JustifyMethod::Left,
}
}
#[must_use]
pub fn with_style(mut self, style: Style) -> Self {
self.style = Some(style);
self
}
#[must_use]
pub fn with_justify(mut self, justify: JustifyMethod) -> Self {
self.justify = justify;
self
}
fn substitute(&self, task: &Task) -> String {
let mut result = self.text.clone();
result = result.replace("{task.description}", &task.description);
if result.contains("{task.percentage") {
let pct = task.percentage();
if let Some(start) = result.find("{task.percentage:") {
if let Some(end) = result[start..].find('}') {
let spec = &result[start..start + end + 1];
let formatted = if spec.contains(".0f") {
format!("{pct:.0}")
} else if spec.contains(".1f") {
format!("{pct:.1}")
} else if spec.contains(".2f") {
format!("{pct:.2}")
} else {
format!("{pct:.1}")
};
result = result.replace(spec, &formatted);
}
}
result = result.replace("{task.percentage}", &format!("{pct:.1}"));
}
result = result.replace("{task.completed}", &format!("{}", task.completed));
let total_str = match task.total {
Some(t) => format!("{t}"),
None => "?".to_string(),
};
result = result.replace("{task.total}", &total_str);
let speed_str = match task.speed() {
Some(s) => format!("{s:.1}"),
None => "?".to_string(),
};
result = result.replace("{task.speed}", &speed_str);
for (key, value) in &task.fields {
let placeholder = format!("{{task.fields.{key}}}");
result = result.replace(&placeholder, value);
}
result
}
}
impl ProgressColumn for TextColumn {
fn render(&self, task: &Task) -> Text {
let content = self.substitute(task);
let style = self.style.clone().unwrap_or_else(Style::null);
let mut text = Text::new(&content, style);
text.justify = Some(self.justify);
text
}
}