fn map_color(color: &str) -> Option<&str> {
match color {
"normal" => Some("\x1b[0m"),
"black" => Some("\x1b[30m"),
"red" => Some("\x1b[31m"),
"green" => Some("\x1b[32m"),
"yellow" => Some("\x1b[33m"),
"blue" => Some("\x1b[34m"),
"magenta" => Some("\x1b[35m"),
"cyan" => Some("\x1b[36m"),
"white" => Some("\x1b[37m"),
"bright black" => Some("\x1b[90m"),
"bright red" => Some("\x1b[91m"),
"bright green" => Some("\x1b[92m"),
"bright yellow" => Some("\x1b[93m"),
"bright blue" => Some("\x1b[94m"),
"bright magenta" => Some("\x1b[95m"),
"bright cyan" => Some("\x1b[96m"),
"bright white" => Some("\x1b[97m"),
_ => None,
}
}
fn map_background(background: &str) -> Option<&str> {
match background {
"normal" => Some("\x1b[0m"),
"black" => Some("\x1b[40m"),
"red" => Some("\x1b[41m"),
"green" => Some("\x1b[42m"),
"yellow" => Some("\x1b[43m"),
"blue" => Some("\x1b[44m"),
"magenta" => Some("\x1b[45m"),
"cyan" => Some("\x1b[46m"),
"white" => Some("\x1b[47m"),
"bright black" => Some("\x1b[100m"),
"bright red" => Some("\x1b[101m"),
"bright green" => Some("\x1b[102m"),
"bright yellow" => Some("\x1b[103m"),
"bright blue" => Some("\x1b[104m"),
"bright magenta" => Some("\x1b[105m"),
"bright cyan" => Some("\x1b[106m"),
"bright white" => Some("\x1b[107m"),
_ => None,
}
}
fn map_style(style: &str) -> Option<&str> {
match style {
"normal" => Some("\x1b[0m"),
"bold" => Some("\x1b[1m"),
"faint" => Some("\x1b[2m"),
"italic" => Some("\x1b[3m"),
"underline" => Some("\x1b[4m"),
_ => None,
}
}
pub trait Colored {
fn color(&mut self, color: &str) -> &mut Self;
fn background(&mut self, background: &str) -> &mut Self;
fn style(&mut self, style: &str) -> &mut Self;
}
impl Colored for String {
fn color(&mut self, color: &str) -> &mut Self {
map_color(color).map(|c| {
self.insert_str(0, c);
self.push_str("\x1b[0m");
});
self
}
fn background(&mut self, background: &str) -> &mut Self {
map_background(background).map(|b| {
self.insert_str(0, b);
self.push_str("\x1b[0m");
});
self
}
fn style(&mut self, style: &str) -> &mut Self {
map_style(style).map(|s| {
self.insert_str(0, s);
self.push_str("\x1b[0m");
});
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_match() {
let mut s = String::from("colorama");
s.color("unknown");
assert_eq!(s, "colorama");
}
#[test]
fn color_and_style() {
let mut s = String::from("colorama");
s.color("red").style("bold");
assert_eq!(s, "\x1b[1m\x1b[31mcolorama\x1b[0m\x1b[0m");
}
#[test]
fn color_background_and_style() {
let mut s = String::from("colorama");
s.color("red").background("green").style("bold");
assert_eq!(s, "\x1b[1m\x1b[42m\x1b[31mcolorama\x1b[0m\x1b[0m\x1b[0m");
}
}