use serenity::all::MessageBuilder; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum Align { Left, Middle, Right, } impl Align { fn pad(self, input: &str, len: usize) -> String { match self { Align::Left => format!("{: format!("{:^len$}", input), Align::Right => format!("{:>len$}", input), } } } pub fn table_formatting + std::fmt::Debug, Ts: AsRef<[[S; N]]>>( headers: &[&'static str; N], padding: &[Align; N], table: Ts, ) -> String { let table = table.as_ref(); // get length for each column let lens = headers .iter() .enumerate() .map(|(i, header)| { table .iter() .map(|r| r.as_ref()[i].as_ref().len()) .max() .unwrap_or(0) .max(header.len()) }) .collect::>(); // paint with message builder let mut m = MessageBuilder::new(); m.push_line("```"); // headers first for (i, header) in headers.iter().enumerate() { if i > 0 { m.push(" | "); } m.push(padding[i].pad(header, lens[i])); } m.push_line(""); // separator m.push_line(format!( "{:-() + (lens.len() - 1) * 3 )); // table itself for row in table { let row = row.as_ref(); for (i, cell) in row.iter().enumerate() { if i > 0 { m.push(" | "); } let cell = cell.as_ref(); m.push(padding[i].pad(cell, lens[i])); } m.push_line(""); } m.push("```"); m.build() }