#[derive(Eq, PartialEq, Clone, Copy)]
#[cfg_attr(
feature = "derive_serde_style",
derive(serde::Deserialize, serde::Serialize)
)]
pub struct Style {
pub foreground: Option<Color>,
pub background: Option<Color>,
pub is_bold: bool,
pub is_dimmed: bool,
pub is_italic: bool,
pub is_underline: bool,
pub is_blink: bool,
pub is_reverse: bool,
pub is_hidden: bool,
pub is_strikethrough: bool,
pub prefix_with_reset: bool,
}
impl Style {
pub fn new() -> Style {
Style::default()
}
pub const fn reset_before_style(&self) -> Style {
Style {
prefix_with_reset: true,
..*self
}
}
pub const fn bold(&self) -> Style {
Style {
is_bold: true,
..*self
}
}
pub const fn dimmed(&self) -> Style {
Style {
is_dimmed: true,
..*self
}
}
pub const fn italic(&self) -> Style {
Style {
is_italic: true,
..*self
}
}
pub const fn underline(&self) -> Style {
Style {
is_underline: true,
..*self
}
}
pub const fn blink(&self) -> Style {
Style {
is_blink: true,
..*self
}
}
pub const fn reverse(&self) -> Style {
Style {
is_reverse: true,
..*self
}
}
pub const fn hidden(&self) -> Style {
Style {
is_hidden: true,
..*self
}
}
pub const fn strikethrough(&self) -> Style {
Style {
is_strikethrough: true,
..*self
}
}
pub const fn fg(&self, foreground: Color) -> Style {
Style {
foreground: Some(foreground),
..*self
}
}
pub const fn on(&self, background: Color) -> Style {
Style {
background: Some(background),
..*self
}
}
pub fn is_plain(self) -> bool {
self == Style::default()
}
}
impl Default for Style {
fn default() -> Style {
Style {
foreground: None,
background: None,
is_bold: false,
is_dimmed: false,
is_italic: false,
is_underline: false,
is_blink: false,
is_reverse: false,
is_hidden: false,
is_strikethrough: false,
prefix_with_reset: false,
}
}
}
#[derive(Eq, PartialEq, Clone, Copy, Debug, Default)]
#[cfg_attr(
feature = "derive_serde_style",
derive(serde::Deserialize, serde::Serialize)
)]
pub enum Color {
Black,
DarkGray,
Red,
LightRed,
Green,
LightGreen,
Yellow,
LightYellow,
Blue,
LightBlue,
Purple,
LightPurple,
Magenta,
LightMagenta,
Cyan,
LightCyan,
White,
LightGray,
Fixed(u8),
Rgb(u8, u8, u8),
#[default]
Default,
}
impl Color {
pub fn normal(self) -> Style {
Style {
foreground: Some(self),
..Style::default()
}
}
pub fn bold(self) -> Style {
Style {
foreground: Some(self),
is_bold: true,
..Style::default()
}
}
pub fn dimmed(self) -> Style {
Style {
foreground: Some(self),
is_dimmed: true,
..Style::default()
}
}
pub fn italic(self) -> Style {
Style {
foreground: Some(self),
is_italic: true,
..Style::default()
}
}
pub fn underline(self) -> Style {
Style {
foreground: Some(self),
is_underline: true,
..Style::default()
}
}
pub fn blink(self) -> Style {
Style {
foreground: Some(self),
is_blink: true,
..Style::default()
}
}
pub fn reverse(self) -> Style {
Style {
foreground: Some(self),
is_reverse: true,
..Style::default()
}
}
pub fn hidden(self) -> Style {
Style {
foreground: Some(self),
is_hidden: true,
..Style::default()
}
}
pub fn strikethrough(self) -> Style {
Style {
foreground: Some(self),
is_strikethrough: true,
..Style::default()
}
}
pub fn reset_before_style(self) -> Style {
Style {
foreground: Some(self),
prefix_with_reset: true,
..Style::default()
}
}
pub fn on(self, background: Color) -> Style {
Style {
foreground: Some(self),
background: Some(background),
..Style::default()
}
}
}
impl From<Color> for Style {
fn from(color: Color) -> Style {
color.normal()
}
}
#[cfg(test)]
#[cfg(feature = "derive_serde_style")]
mod serde_json_tests {
use super::{Color, Style};
#[test]
fn color_serialization() {
let colors = &[
Color::Red,
Color::Blue,
Color::Rgb(123, 123, 123),
Color::Fixed(255),
];
assert_eq!(
serde_json::to_string(&colors).unwrap(),
"[\"Red\",\"Blue\",{\"Rgb\":[123,123,123]},{\"Fixed\":255}]"
);
}
#[test]
fn color_deserialization() {
let colors = [
Color::Red,
Color::Blue,
Color::Rgb(123, 123, 123),
Color::Fixed(255),
];
for color in colors {
let serialized = serde_json::to_string(&color).unwrap();
let deserialized: Color = serde_json::from_str(&serialized).unwrap();
assert_eq!(color, deserialized);
}
}
#[test]
fn style_serialization() {
let style = Style::default();
assert_eq!(serde_json::to_string(&style).unwrap(), "{\"foreground\":null,\"background\":null,\"is_bold\":false,\"is_dimmed\":false,\"is_italic\":false,\"is_underline\":false,\"is_blink\":false,\"is_reverse\":false,\"is_hidden\":false,\"is_strikethrough\":false,\"prefix_with_reset\":false}".to_string());
}
}