[−][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