[][src]Function tao_of_rust::ch07::structs::color_terminal

pub fn color_terminal()

结构体: 面向对象示例

Base usage: 让终端的输出带上颜色 color.rs

use std::fmt;

struct ColoredString {
    input: String,
    fgcolor: String,
    bgcolor: String,
}

impl Default for ColoredString {
    fn default() -> Self {
        ColoredString {
            input: String::default(),
            fgcolor: String::new(),
            bgcolor: String::new(),
        }
    }
}

impl ColoredString{
    fn compute_style(&self) -> String {
        let mut res = String::from("\x1B[");
        let mut has_wrote = false;
        if !self.bgcolor.is_empty() {
            res.push_str(&self.bgcolor);
            has_wrote = true;
        }
        if !self.fgcolor.is_empty() {
            if has_wrote {
                res.push(';');
            }
            res.push_str(&self.fgcolor);
        }
        res.push('m');
        res
    }
}

trait Colorize {
    fn red(self) -> ColoredString;
    fn on_yellow(self) -> ColoredString;
}
impl<'a> Colorize for ColoredString {
    fn red(self) -> ColoredString {
        ColoredString{ fgcolor: String::from("31"), ..self  }
    }
    fn on_yellow(self) -> ColoredString {
        ColoredString { bgcolor: String::from("43"), ..self }
    }
}
impl<'a> Colorize for &'a str {
    fn red(self) -> ColoredString {
        ColoredString {
            fgcolor: String::from("31"),
            input: String::from(self),
            ..ColoredString::default()
        }
    }
    fn on_yellow(self) -> ColoredString {
        ColoredString {
            bgcolor: String::from("43"),
            input: String::from(self),
            ..ColoredString::default()
        }
    }
}

impl fmt::Display for ColoredString {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut input = &self.input.clone();
        try!(f.write_str(&self.compute_style()));
        try!(f.write_str(input));
        try!(f.write_str("\x1B[0m"));
        Ok(())
    }
}

/*
格式参考
$ echo "\e[31;43mHello\e[0m"
$ echo "\x1B[31;43mHello\x1B[0m"
$ echo "\033[31;43mHello\033[0m"

*/
fn main() {
    let hi = "Hello".red().on_yellow();
    println!("{}", hi);
    let hi = "Hello".on_yellow();
    println!("{}", hi);
    let hi = "Hello".red();
    println!("{}", hi);
    let hi = "Hello".on_yellow().red();
    println!("{}", hi);
}Run

Base usage: 【重构】让终端的输出带上颜色 color.rs

下面代码最好手工复制到play.rust-lang.org执行

use std::convert::From;
use std::str::FromStr;
use std::string::String;
use std::fmt;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Color {
    Red,
    Yellow,
    Blue,
}

impl Color {
    pub fn to_fg_str(&self) -> &str {
        match *self {
            Color::Red => "31",
            Color::Yellow => "33",
            Color::Blue => "34",
        }
    }
    pub fn to_bg_str(&self) -> &str {
        match *self {
            Color::Red => "41",
            Color::Yellow => "43",
            Color::Blue => "44",
        }
    }
}

impl<'a> From<&'a str> for Color {
    fn from(src: &str) -> Self {
        src.parse().unwrap_or(Color::Red)
    }
}
impl From<String> for Color {
    fn from(src: String) -> Self {
        src.parse().unwrap_or(Color::Red)
    }
}
impl FromStr for Color {
    type Err = ();
    fn from_str(src: &str) -> Result<Self, Self::Err> {
        let src = src.to_lowercase();
        match src.as_ref() {
            "red" => Ok(Color::Red),
            "yellow" => Ok(Color::Yellow),
            "blue" => Ok(Color::Blue),
            _ => Err(()),
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
struct ColoredString {
    input: String,
    fgcolor: Option<Color>,
    bgcolor: Option<Color>,
}



impl ColoredString {
    fn compute_style(&self) -> String {
        let mut res = String::from("\x1B[");
        let mut has_wrote = false;
        if let Some(ref bgcolor) = self.bgcolor {
            if has_wrote {
                res.push(';');
            }
            res.push_str(bgcolor.to_bg_str());
            has_wrote = true;
        }
        if let Some(ref fgcolor) = self.fgcolor {
            if has_wrote {
                res.push(';');
            }
            res.push_str(fgcolor.to_fg_str());
        }
        res.push('m');
        res
    }
}


impl Default for ColoredString {
    fn default() -> Self {
        ColoredString {
            input: String::default(),
            fgcolor: None,
            bgcolor: None,
        }
    }
}

// impl<'a> From<&'a str> for ColoredString {
//     fn from(s: &'a str) -> Self {
//         ColoredString { input: String::from(s), ..ColoredString::default() }
//     }
// }

trait Colorize {
    fn red(self) -> ColoredString;
    fn yellow(self) -> ColoredString;
    fn blue(self) -> ColoredString;
    fn color<S: Into<Color>>(self, color: S) -> ColoredString;
    fn on_red(self) -> ColoredString;
    fn on_yellow(self) -> ColoredString;
    fn on_blue(self) -> ColoredString;
    fn on_color<S: Into<Color>>(self, color: S) -> ColoredString;
}
impl Colorize for ColoredString {
    fn red(self) -> ColoredString {self.color(Color::Red)}
    fn yellow(self) -> ColoredString {self.color(Color::Yellow)}
    fn blue(self) -> ColoredString {self.color(Color::Blue)}
    fn color<S: Into<Color>>(self, color: S) -> ColoredString {
        ColoredString { fgcolor: Some(color.into()), ..self }
    }
    fn on_red(self) -> ColoredString {self.on_color(Color::Red)}
    fn on_yellow(self) -> ColoredString {self.on_color(Color::Yellow)}
    fn on_blue(self) -> ColoredString {self.on_color(Color::Blue)}
    fn on_color<S: Into<Color>>(self, color: S) -> ColoredString {
        ColoredString { bgcolor: Some(color.into()), ..self }
    }
}
impl<'a> Colorize for &'a str {
    fn red(self) -> ColoredString {self.color(Color::Red)}
    fn yellow(self) -> ColoredString {self.color(Color::Yellow)}
    fn blue(self) -> ColoredString {self.color(Color::Blue)}
    fn color<S: Into<Color>>(self, color: S) -> ColoredString {
        ColoredString {
            fgcolor: Some(color.into()),
            input: String::from(self),
            ..ColoredString::default()
        }
    }
    fn on_red(self) -> ColoredString {self.on_color(Color::Red)}
    fn on_yellow(self) -> ColoredString {self.on_color(Color::Yellow)}
    fn on_blue(self) -> ColoredString {self.on_color(Color::Blue)}
    fn on_color<S: Into<Color>>(self, color: S) -> ColoredString {
        ColoredString {
            bgcolor: Some(color.into()),
            input: String::from(self),
            ..ColoredString::default()
        }
    }
}

impl fmt::Display for ColoredString {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut input = &self.input.clone();

        try!(f.write_str(&self.compute_style()));
        try!(f.write_str(input));
        try!(f.write_str("\x1B[0m"));
        Ok(())
    }
}

fn main() {
    let red = "red".red();
    println!("{}", red);
    let yellow = "yellow".yellow().on_blue();
    println!("{}", yellow);
    let blue = "blue".blue();
    println!("{}", blue);
    let red = "red".color("red");
    println!("{}", red);
    let yellow = "yellow".on_color("yellow");
    println!("{}", yellow);
}Run