exa/colours.rs

105 lines
4.0 KiB
Rust
Raw Normal View History

2014-05-03 10:30:37 +00:00
pub enum Colour {
2014-05-26 19:24:51 +00:00
// These are the standard numeric sequences.
// See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
2014-05-03 10:30:37 +00:00
Black = 30, Red = 31, Green = 32, Yellow = 33, Blue = 34, Purple = 35, Cyan = 36, White = 37,
}
2014-05-26 19:24:51 +00:00
// There are only three different styles: plain (no formatting), only
// a foreground colour, and a catch-all for anything more complicated
// than that. It's technically possible to write other cases such as
// "bold foreground", but probably isn't worth writing all the code.
2014-05-03 10:30:37 +00:00
pub enum Style {
Plain,
Foreground(Colour),
Style(StyleStruct),
}
2014-05-26 19:24:51 +00:00
// Having a struct inside an enum is currently unfinished in Rust, but
// should be put in there when that feature is complete.
2014-05-04 20:35:10 +00:00
pub struct StyleStruct {
2014-05-03 10:30:37 +00:00
foreground: Colour,
background: Option<Colour>,
bold: bool,
underline: bool,
}
impl Style {
2014-05-26 10:08:33 +00:00
pub fn paint(&self, input: &str) -> String {
2014-05-03 10:30:37 +00:00
match *self {
Plain => input.to_string(),
2014-05-03 10:30:37 +00:00
Foreground(c) => c.paint(input),
Style(s) => match s {
StyleStruct { foreground, background, bold, underline } => {
let bg = match background {
2014-05-03 10:30:37 +00:00
Some(c) => format!("{};", c as int + 10),
None => "".to_string()
2014-05-03 10:30:37 +00:00
};
let bo = if bold { "1;" } else { "" };
let un = if underline { "4;" } else { "" };
let painted = format!("\x1B[{}{}{}{}m{}\x1B[0m", bo, un, bg, foreground as int, input.to_string());
return painted.to_string();
2014-05-03 10:30:37 +00:00
}
}
}
}
}
impl Style {
pub fn bold(&self) -> Style {
match *self {
2014-05-26 19:24:51 +00:00
Plain => Style(StyleStruct { foreground: White, background: None, bold: true, underline: false }),
Foreground(c) => Style(StyleStruct { foreground: c, background: None, bold: true, underline: false }),
Style(st) => Style(StyleStruct { foreground: st.foreground, background: st.background, bold: true, underline: false }),
2014-05-03 10:30:37 +00:00
}
}
pub fn underline(&self) -> Style {
match *self {
2014-05-26 19:24:51 +00:00
Plain => Style(StyleStruct { foreground: White, background: None, bold: false, underline: true }),
Foreground(c) => Style(StyleStruct { foreground: c, background: None, bold: false, underline: true }),
Style(st) => Style(StyleStruct { foreground: st.foreground, background: st.background, bold: false, underline: true }),
2014-05-03 10:30:37 +00:00
}
}
pub fn on(&self, background: Colour) -> Style {
match *self {
2014-05-26 19:24:51 +00:00
Plain => Style(StyleStruct { foreground: White, background: Some(background), bold: false, underline: false }),
Foreground(c) => Style(StyleStruct { foreground: c, background: Some(background), bold: false, underline: false }),
Style(st) => Style(StyleStruct { foreground: st.foreground, background: Some(background), bold: false, underline: false }),
2014-05-03 10:30:37 +00:00
}
}
}
impl Colour {
2014-05-26 19:24:51 +00:00
// This is a short-cut so you don't have to use Blue.normal() just
// to turn Blue into a Style.
2014-05-26 10:08:33 +00:00
pub fn paint(&self, input: &str) -> String {
let re = format!("\x1B[{}m{}\x1B[0m", *self as int, input);
return re.to_string();
2014-05-03 10:30:37 +00:00
}
pub fn underline(&self) -> Style {
Style(StyleStruct { foreground: *self, background: None, bold: false, underline: true })
}
pub fn bold(&self) -> Style {
Style(StyleStruct { foreground: *self, background: None, bold: true, underline: false })
}
pub fn normal(&self) -> Style {
Style(StyleStruct { foreground: *self, background: None, bold: false, underline: false })
}
pub fn on(&self, background: Colour) -> Style {
Style(StyleStruct { foreground: *self, background: Some(background), bold: false, underline: false })
}
}
2014-05-26 10:08:33 +00:00
pub fn strip_formatting(input: &String) -> String {
let re = regex!("\x1B\\[.+?m");
re.replace_all(input.as_slice(), "").to_string()
}