use colored::Colorize;
use comfy_table::{presets::UTF8_BORDERS_ONLY, Cell, Table};
use serde::Serialize;
use crate::types::StoredMessage;
pub fn print_json<T: Serialize>(data: &T) {
match serde_json::to_string_pretty(data) {
Ok(s) => println!("{}", s),
Err(e) => err(&format!("JSON serialization failed: {}", e)),
}
}
pub fn print_table(headers: &[&str], rows: &[Vec<String>]) {
let mut t = Table::new();
t.load_preset(UTF8_BORDERS_ONLY);
t.set_header(headers.iter().map(Cell::new));
for row in rows {
t.add_row(row.iter().map(Cell::new));
}
println!("{}", t);
}
pub fn success(msg: &str) {
println!("{} {}", "✓".green().bold(), msg);
}
pub fn err(msg: &str) {
eprintln!("{} {}", "✗".red().bold(), msg.red());
}
pub fn warn(msg: &str) {
eprintln!("{} {}", "!".yellow().bold(), msg.yellow());
}
pub fn dim(msg: &str) {
eprintln!("{}", msg.dimmed());
}
pub fn format_message(m: &StoredMessage) -> String {
let ts = m.timestamp.format("%Y-%m-%d %H:%M:%S").to_string();
let chan = m.channel_name.as_deref().unwrap_or("");
let chan_part = if chan.is_empty() {
String::new()
} else {
format!("#{} | ", chan)
};
let content = m.content.replace('\n', " ");
let content = if content.chars().count() > 300 {
let truncated: String = content.chars().take(300).collect();
format!("{}…", truncated)
} else {
content
};
format!(
"{} {}{}: {}",
ts.dimmed(),
chan_part.cyan(),
m.sender_name.bold(),
content
)
}