use console::{StyledObject, style};
use std::fmt;
pub fn title(text: impl fmt::Display) -> StyledObject<String> {
style(text.to_string()).cyan().bold()
}
pub fn section(text: impl fmt::Display) -> StyledObject<String> {
style(text.to_string()).bold()
}
pub fn meta(text: impl fmt::Display) -> StyledObject<String> {
style(text.to_string()).dim()
}
pub fn success(text: impl fmt::Display) -> StyledObject<String> {
style(text.to_string()).green()
}
pub fn warning(text: impl fmt::Display) -> StyledObject<String> {
style(text.to_string()).yellow()
}
pub fn kv(label: &str, value: impl fmt::Display) {
println!(" {:<13} {}", meta(format!("{label}:")), value);
}
pub fn action_note(text: impl fmt::Display) {
println!(" {}", meta(text));
}
pub fn divider(width: usize) -> String {
"-".repeat(width)
}
pub fn truncate_end(value: &str, max: usize) -> String {
let char_count = value.chars().count();
if char_count <= max {
return value.to_string();
}
if max <= 3 {
return ".".repeat(max);
}
let mut out = String::new();
for ch in value.chars().take(max - 3) {
out.push(ch);
}
out.push_str("...");
out
}
pub fn truncate_middle(value: &str, max: usize) -> String {
let char_count = value.chars().count();
if char_count <= max {
return value.to_string();
}
if max <= 3 {
return ".".repeat(max);
}
let keep = max - 3;
let prefix_len = keep / 2;
let suffix_len = keep - prefix_len;
let prefix: String = value.chars().take(prefix_len).collect();
let suffix: String = value
.chars()
.rev()
.take(suffix_len)
.collect::<Vec<_>>()
.into_iter()
.rev()
.collect();
format!("{prefix}...{suffix}")
}