93 lines
2.5 KiB
Rust
93 lines
2.5 KiB
Rust
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<Color> 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<T: Display>(str: T) {
|
|
println!("{}", style(str).white().bold());
|
|
}
|
|
|
|
pub fn header<T: Display>(str: T) {
|
|
println!(
|
|
"{} {} {}",
|
|
style("-=[").red().dim(),
|
|
style(str).white().bold(),
|
|
style("]=-").red().dim()
|
|
);
|
|
}
|
|
|
|
pub fn note<T: Display>(str: T) {
|
|
println!("{}", style(str).white().dim());
|
|
}
|
|
|
|
pub fn description_list(list: HashMap<String, String>) {
|
|
let mut lines = list.into_iter().collect::<Vec<(String, String)>>();
|
|
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<String> = 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::<String>()
|
|
});
|
|
println!("{}", output);
|
|
}
|
|
|
|
pub fn print<T: Display>(s: T) {
|
|
println!("{}", s);
|
|
}
|
|
|
|
pub fn error<T: Display>(s: T) {
|
|
println!("{}", style(s).red().bold());
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {}
|