字体变色终端
常见于命令行终端会输出变色的字体,这种都是采用 \033[31m 起始特殊字符加上 \033[0m 回滚颜色指令来做字体变色处理, 常见于类似 Python 这样来处理终端颜色字体:
GlobalColors = {
'red': '\033[31m',
'blue': '\033[94m',
'green': '\033[92m',
'yellow': '\033[93m',
'magenta': '\033[35m',
'cyan': '\033[36m'
}
""" 字体变色 """
def colored(strg, color):
col = GlobalColors.get(color, None)
if col:
return col+str(strg)+'\033[0m'
return strg
""" 调用打印 """
if __name__ == '__main__':
print("%s %%\r" % (colored('error!', 'red')), end="")
这样可以看到终端颜色字体输出不是常规的红色字体, 这种就是利用终端特殊字符来做的变色切换,其他语言基本上通用。
Rust
如果简单在 Rust 使用会发现输出异常:
// 字体变色处理, 异常
println!("\033[31m{}\033[0m","hello.world");
实际上这是因为 Rust 默认采用 utf8 编码处理, ‘\033’ 这个特殊字符直接输出成原始字符, 所以需要将其字符手动转化成 \x1b 处理.
// 字体变色处理, 正常变色
println!("\x1b[31m{}\x1b[0m","hello.world");
以这个方法做基础可以封装成自己常用的工具类库:
/// 终端颜色
enum ColorStr<'a> {
Red(&'a str),
Green(&'a str),
Yellow(&'a str),
Blue(&'a str),
}
/// 调用 into 转化成 string 的处理
impl<'a> From<&ColorStr<'a>> for String {
fn from(value: &ColorStr<'a>) -> Self {
match value {
ColorStr::Red(msg) => format!("\x1b[31m{}\x1b[0m", msg),
ColorStr::Green(msg) => format!("\x1b[92m{}\x1b[0m", msg),
ColorStr::Yellow(msg) => format!("\x1b[93m{}\x1b[0m", msg),
ColorStr::Blue(msg) => format!("\x1b[94m{}\x1b[0m", msg),
}
}
}
/// 调用打印的时候的输出转化
impl<'a> Display for ColorStr<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let msg: String = self.into();
write!(f, "{}", msg)
}
}
fn main() {
println!("{}", ColorStr::Red("error: this is red"));
println!("{}", ColorStr::Yellow("warn: this is yellow"));
println!("{}", ColorStr::Green("success: this is green"));
println!("{}", ColorStr::Blue("info: this is blue"));
println!("End");
}
执行之后就能看到五颜六色的终端字体的变色了, 最终封装成 printer.rs 库:
use std::fmt::{Debug, Display, Formatter};
/// cmd font color
///
/// ```rust
/// use tools::Print;
/// println!("{}",Print::Green("hello.world[success]"));
/// println!("{}",Print::Red("hello.world[red]"))
/// ```
#[allow(dead_code)]
pub enum Print<'a> {
Black(&'a str),
DarkGray(&'a str),
Blue(&'a str),
LightBlue(&'a str),
Green(&'a str),
LightGreen(&'a str),
Cyan(&'a str),
LightCyan(&'a str),
Red(&'a str),
LightRed(&'a str),
Purple(&'a str),
LightPurple(&'a str),
Yellow(&'a str),
LightYellow(&'a str),
LightGray(&'a str),
White(&'a str),
}
impl<'a> Display for Print<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Black(s) => write!(f, "\x1b[0;30m{}\x1b[0m", s),
Self::DarkGray(s) => write!(f, "\x1b[1;30m{}\x1b[0m", s),
Self::Blue(s) => write!(f, "\x1b[0;34m{}\x1b[0m", s),
Self::LightBlue(s) => write!(f, "\x1b[1;34m{}\x1b[0m", s),
Self::Green(s) => write!(f, "\x1b[0;32m{}\x1b[0m", s),
Self::LightGreen(s) => write!(f, "\x1b[1;32m{}\x1b[0m", s),
Self::Cyan(s) => write!(f, "\x1b[0;36m{}\x1b[0m", s),
Self::LightCyan(s) => write!(f, "\x1b[1;36m{}\x1b[0m", s),
Self::Red(s) => write!(f, "\x1b[0;31m{}\x1b[0m", s),
Self::LightRed(s) => write!(f, "\x1b[1;31m{}\x1b[0m", s),
Self::Purple(s) => write!(f, "\x1b[0;35m{}\x1b[0m", s),
Self::LightPurple(s) => write!(f, "\x1b[1;35m{}\x1b[0m", s),
Self::Yellow(s) => write!(f, "\x1b[0;33m{}\x1b[0m", s),
Self::LightYellow(s) => write!(f, "\x1b[1;33m{}\x1b[0m", s),
Self::LightGray(s) => write!(f, "\x1b[0;37m{}\x1b[0m", s),
Self::White(s) => write!(f, "\x1b[1;37m{}\x1b[0m", s),
}
}
}
impl<'a> Debug for Print<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f,"{}",self)
}
}