#![crate_name = "colorize"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![allow(unstable)]
use Color::*;
use BgColor::*;
use Style::*;
use std::mem;
use std::str::FromStr;
#[derive(Clone, Copy)]
pub enum Color {
Black = 30,
Red = 31,
Green = 32,
Yellow = 33,
Blue = 34,
Magenta = 35,
Cyan = 36,
Grey = 37,
Default = 39,
BrightBlack = 90,
BrightRed = 91,
BrightGreen = 92,
BrightYellow = 93,
BrightBlue = 94,
BrightMagenta = 95,
BrightCyan = 96,
BrightGrey = 97
}
#[derive(Clone, Copy)]
pub enum BgColor {
Blackb = 40,
Redb = 41,
Greenb = 42,
Yellowb = 43,
Blueb = 44,
Magentab = 45,
Cyanb = 46,
Greyb = 47,
Defaultb = 49,
BrightBlackb = 100,
BrightRedb = 101,
BrightGreenb = 102,
BrightYellowb = 103,
BrightBlueb = 104,
BrightMagentab = 105,
BrightCyanb = 106,
BrightGreyb = 107
}
#[derive(Clone, Copy)]
pub enum Style {
Underscore = 4,
Bold = 1,
Blink = 5,
Reverse = 7,
Concealed = 8,
Faint = 2,
Italic = 3,
CrossedOut = 9
}
impl internal::TermAttrib for Color {
fn to_int(&self) -> i32 { *self as i32 }
}
impl internal::TermAttrib for BgColor {
fn to_int(&self) -> i32 { *self as i32 }
}
impl internal::TermAttrib for Style {
fn to_int(&self) -> i32 { *self as i32 }
}
impl BgColor {
fn from_fg(color: Color) -> BgColor {
unsafe { mem::transmute(color as i8 + 10) }
}
}
mod internal {
use super::{Color, BgColor};
use std::cell::RefCell;
static DEFAULT_FG: i32 = 39;
static DEFAULT_BG: i32 = 49;
thread_local!(static GLOB_COLOR: RefCell<GlobalColor> = RefCell::new(GlobalColor {fg: DEFAULT_FG, bg: DEFAULT_BG}));
pub trait TermAttrib {
fn to_int(&self) -> i32;
}
#[derive(Clone)]
pub struct GlobalColor {
fg: i32,
bg: i32
}
impl Drop for GlobalColor {
fn drop(&mut self) {
print!("\x1b[0;{};{}m", DEFAULT_FG, DEFAULT_BG)
}
}
fn get_glob() -> (i32, i32) {
GLOB_COLOR.with (|cell| {let g = cell.borrow(); (g.fg, g.bg)})
}
pub fn global_color(fg_color: Option<Color>, bg_color: Option<BgColor>) {
GLOB_COLOR.with (|cell| {
let mut g = cell.borrow_mut();
match fg_color {
Some(c) => g.fg = c.to_int(),
None => g.fg = DEFAULT_FG
}
match bg_color {
Some(c) => g.bg = c.to_int(),
None => g.bg = DEFAULT_BG
}
})
}
pub fn pack<T: TermAttrib>(attrib: T, mut text: String) -> String {
if text.as_str().starts_with("\x1b[") {
unsafe {
text.as_mut_vec().remove(0);
text.as_mut_vec().remove(0);
}
let tmp = text;
text = String::from("\x1b[");
text.push_str(format!("{};", attrib.to_int()).as_str());
text.push_str(tmp.as_str());
} else {
let tmp = text;
text = format!("\x1b[{}m", attrib.to_int());
text.push_str(tmp.as_str());
let (fg, bg) = get_glob();
text.push_str(format!("\x1b[0;{};{}m", fg, bg).as_str());
}
text
}
}
pub fn global_fg(color: Color) {
internal::global_color(Some(color), None)
}
pub fn global_bg(color: Color) {
internal::global_color(None, Some(BgColor::from_fg(color)))
}
pub fn reset() {
internal::global_color(Some(Default), Some(Defaultb))
}
pub trait AnsiColor {
fn black(self) -> String;
fn red(self) -> String;
fn green(self) -> String;
fn yellow(self) -> String;
fn blue(self) -> String;
fn magenta(self) -> String;
fn cyan(self) -> String;
fn grey(self) -> String;
fn b_black(self) -> String;
fn b_red(self) -> String;
fn b_green(self) -> String;
fn b_yellow(self) -> String;
fn b_blue(self) -> String;
fn b_magenta(self) -> String;
fn b_cyan(self) -> String;
fn b_grey(self) -> String;
fn default(self) -> String;
fn blackb(self) -> String;
fn redb(self) -> String;
fn greenb(self) -> String;
fn yellowb(self) -> String;
fn blueb(self) -> String;
fn magentab(self) -> String;
fn cyanb(self) -> String;
fn greyb(self) -> String;
fn b_blackb(self) -> String;
fn b_redb(self) -> String;
fn b_greenb(self) -> String;
fn b_yellowb(self) -> String;
fn b_blueb(self) -> String;
fn b_magentab(self) -> String;
fn b_cyanb(self) -> String;
fn b_greyb(self) -> String;
fn defaultb(self) -> String;
fn underlined(self) -> String;
fn bold(self) -> String;
fn blink(self) -> String;
fn reverse(self) -> String;
fn concealed(self) -> String;
fn faint(self) -> String;
fn italic(self) -> String;
fn crossedout(self) -> String;
}
impl AnsiColor for String {
fn black(self) -> String { internal::pack(Black, self) }
fn red(self) -> String { internal::pack(Red, self) }
fn green(self) -> String { internal::pack(Green, self) }
fn yellow(self) -> String { internal::pack(Yellow, self) }
fn blue(self) -> String { internal::pack(Blue, self) }
fn magenta(self) -> String { internal::pack(Magenta, self) }
fn cyan(self) -> String { internal::pack(Cyan, self) }
fn grey(self) -> String { internal::pack(Grey, self) }
fn b_black(self) -> String { internal::pack(BrightBlack, self) }
fn b_red(self) -> String { internal::pack(BrightRed, self) }
fn b_green(self) -> String { internal::pack(BrightGreen, self) }
fn b_yellow(self) -> String { internal::pack(BrightYellow, self) }
fn b_blue(self) -> String { internal::pack(BrightBlue, self) }
fn b_magenta(self) -> String { internal::pack(BrightMagenta, self) }
fn b_cyan(self) -> String { internal::pack(BrightCyan, self) }
fn b_grey(self) -> String { internal::pack(BrightGrey, self) }
fn default(self) -> String { internal::pack(Default, self) }
fn blackb(self) -> String { internal::pack(Blackb, self) }
fn redb(self) -> String { internal::pack(Redb, self) }
fn greenb(self) -> String { internal::pack(Greenb, self) }
fn yellowb(self) -> String { internal::pack(Yellowb, self) }
fn blueb(self) -> String { internal::pack(Blueb, self) }
fn magentab(self) -> String { internal::pack(Magentab, self) }
fn cyanb(self) -> String { internal::pack(Cyanb, self) }
fn greyb(self) -> String { internal::pack(Greyb, self) }
fn b_blackb(self) -> String { internal::pack(BrightBlackb, self) }
fn b_redb(self) -> String { internal::pack(BrightRedb, self) }
fn b_greenb(self) -> String { internal::pack(BrightGreenb, self) }
fn b_yellowb(self) -> String { internal::pack(BrightYellowb, self) }
fn b_blueb(self) -> String { internal::pack(BrightBlueb, self) }
fn b_magentab(self) -> String { internal::pack(BrightMagentab, self) }
fn b_cyanb(self) -> String { internal::pack(BrightCyanb, self) }
fn b_greyb(self) -> String { internal::pack(BrightGreyb, self) }
fn defaultb(self) -> String { internal::pack(Defaultb, self) }
fn underlined(self) -> String { internal::pack(Underscore, self) }
fn bold(self) -> String { internal::pack(Bold, self) }
fn blink(self) -> String { internal::pack(Blink, self) }
fn reverse(self) -> String { internal::pack(Reverse, self) }
fn concealed(self) -> String { internal::pack(Concealed, self) }
fn faint(self) -> String { internal::pack(Faint, self) }
fn italic(self) -> String { internal::pack(Italic, self) }
fn crossedout(self) -> String { internal::pack(CrossedOut, self) }
}
impl AnsiColor for &'static str {
fn black(self) -> String { String::from(self).black() }
fn red(self) -> String { String::from(self).red() }
fn green(self) -> String { String::from(self).green() }
fn yellow(self) -> String { String::from(self).yellow() }
fn blue(self) -> String { String::from(self).blue() }
fn magenta(self) -> String { String::from(self).magenta() }
fn cyan(self) -> String { String::from(self).cyan() }
fn grey(self) -> String { String::from(self).grey() }
fn default(self) -> String { String::from(self).default() }
fn b_black(self) -> String { String::from(self).b_black() }
fn b_red(self) -> String { String::from(self).b_red() }
fn b_green(self) -> String { String::from(self).b_green() }
fn b_yellow(self) -> String { String::from(self).b_yellow() }
fn b_blue(self) -> String { String::from(self).b_blue() }
fn b_magenta(self) -> String { String::from(self).b_magenta() }
fn b_cyan(self) -> String { String::from(self).b_cyan() }
fn b_grey(self) -> String { String::from(self).b_grey() }
fn blackb(self) -> String { String::from(self).blackb() }
fn redb(self) -> String { String::from(self).redb() }
fn greenb(self) -> String { String::from(self).greenb() }
fn yellowb(self) -> String { String::from(self).yellowb() }
fn blueb(self) -> String { String::from(self).blueb() }
fn magentab(self) -> String { String::from(self).magentab() }
fn cyanb(self) -> String { String::from(self).cyanb() }
fn greyb(self) -> String { String::from(self).greyb() }
fn defaultb(self) -> String { String::from(self).defaultb() }
fn b_blackb(self) -> String { String::from(self).b_blackb() }
fn b_redb(self) -> String { String::from(self).b_redb() }
fn b_greenb(self) -> String { String::from(self).b_greenb() }
fn b_yellowb(self) -> String { String::from(self).b_yellowb() }
fn b_blueb(self) -> String { String::from(self).b_blueb() }
fn b_magentab(self) -> String { String::from(self).b_magentab() }
fn b_cyanb(self) -> String { String::from(self).b_cyanb() }
fn b_greyb(self) -> String { String::from(self).b_greyb() }
fn underlined(self) -> String { String::from(self).underlined() }
fn bold(self) -> String { String::from(self).bold() }
fn blink(self) -> String { String::from(self).blink() }
fn reverse(self) -> String { String::from(self).reverse() }
fn concealed(self) -> String { String::from(self).concealed() }
fn faint(self) -> String { String::from(self).faint() }
fn italic(self) -> String { String::from(self).italic() }
fn crossedout(self) -> String { String::from(self).crossedout() }
}