use std::{fmt, fmt::Display};
use chrono::Local;
use strum::{Display, EnumString};
#[derive(Debug, Display, EnumString, Clone)]
pub enum StatusLineOutput {
#[strum(serialize = "log")]
Log,
#[strum(serialize = "all")]
StdOutAndLog,
}
#[derive(Debug, Clone, Default)]
pub struct StatusLine {
fields: Vec<(&'static str, String)>,
}
impl StatusLine {
pub fn new() -> Self {
Default::default()
}
pub fn add<T: ToString>(&mut self, value: T) -> &mut Self {
self.add_field("", value)
}
pub fn add_field<T: ToString>(&mut self, name: &'static str, value: T) -> &mut Self {
self.fields.push((name, value.to_string()));
self
}
}
impl Display for StatusLine {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} ", Local::now().format("%H:%M"))?;
let s = self.fields.iter().map(|(k, v)| format(k, v)).collect::<Vec<_>>();
write!(f, "{}", s.join(" "))
}
}
fn format(k: &&str, v: &str) -> String {
if k.is_empty() {
v.to_string()
} else {
format!("{k}: {v}")
}
}
#[cfg(test)]
mod test {
use super::StatusLine;
#[test]
fn test_do_not_display_empty_keys() {
let mut status = StatusLine::new();
status.add_field("key", "val");
let display = status.to_string();
assert!(display.contains("key: val"));
assert_eq!(display.matches(':').count(), 2);
let mut status = StatusLine::new();
status.add_field("", "val");
let display = status.to_string();
assert!(display.contains("val"));
assert_eq!(display.matches(':').count(), 1);
}
}