use console::style; use std::collections::HashMap; use std::fmt::Display; #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, Copy)] pub enum Color { Black, Red, Green, Yellow, Blue, Magenta, Cyan, White, Color256(u8), } impl From for console::Color { fn from(fr: Color) -> Self { match fr { Color::Black => Self::Black, Color::Red => Self::Red, Color::Green => Self::Green, Color::Yellow => Self::Yellow, Color::Blue => Self::Blue, Color::Magenta => Self::Magenta, Color::Cyan => Self::Cyan, Color::White => Self::White, Color::Color256(v) => Self::Color256(v), } } } pub fn labeled(color: Color, label: &str, msg: &str) { let label = format!("[{}]", label); println!("{} {}", console::style(label).fg(color.into()).bold(), msg); } pub fn message(str: T) { println!("{}", style(str).white().bold()); } pub fn header(str: T) { println!( "{} {} {}", style("-=[").red().dim(), style(str).white().bold(), style("]=-").red().dim() ); } pub fn note(str: T) { println!("{}", style(str).white().dim()); } pub fn description_list(list: HashMap) { let mut lines = list.into_iter().collect::>(); let key_max_length = lines.iter().map(|(v, _)| v.len()).max().unwrap_or(10) + 3; let desc_max_length = 80 - key_max_length; let indent_string = " ".repeat(key_max_length); lines.sort_by(|(a, _), (b, _)| a.cmp(b)); let output = lines.iter().fold(String::new(), |output, (name, desc)| { let spaced_key = format!("{:width$}", name, width = key_max_length); let mut desc_lines: Vec = textwrap::fill(desc, desc_max_length) .split('\n') .map(|s| s.to_string()) .collect(); desc_lines.reverse(); let first_line = desc_lines.pop().unwrap_or_else(String::new); desc_lines.reverse(); output + &format!("{}{}", style(spaced_key).bold(), style(first_line).dim()) + "\n" + &desc_lines .iter() .map(|s| indent_string.clone() + s + "\n") .collect::() }); println!("{}", output); } pub fn print(s: T) { println!("{}", s); } pub fn error(s: T) { println!("{}", style(s).red().bold()); } #[cfg(test)] mod tests {}