use crate::style::{Color, Style};
use crate::text::Span;
pub trait Stylize {
fn style(self, style: Style) -> Span;
fn fg(self, color: Color) -> Span;
fn bg(self, color: Color) -> Span;
fn red(self) -> Span where Self: Sized { self.fg(Color::Red) }
fn green(self) -> Span where Self: Sized { self.fg(Color::Green) }
fn blue(self) -> Span where Self: Sized { self.fg(Color::Blue) }
fn cyan(self) -> Span where Self: Sized { self.fg(Color::Cyan) }
fn yellow(self) -> Span where Self: Sized { self.fg(Color::Yellow) }
fn magenta(self) -> Span where Self: Sized { self.fg(Color::Magenta) }
fn white(self) -> Span where Self: Sized { self.fg(Color::White) }
fn gray(self) -> Span where Self: Sized { self.fg(Color::Gray) }
fn black(self) -> Span where Self: Sized { self.fg(Color::Black) }
fn on_red(self) -> Span where Self: Sized { self.bg(Color::Red) }
fn on_green(self) -> Span where Self: Sized { self.bg(Color::Green) }
fn on_blue(self) -> Span where Self: Sized { self.bg(Color::Blue) }
fn on_cyan(self) -> Span where Self: Sized { self.bg(Color::Cyan) }
fn on_yellow(self) -> Span where Self: Sized { self.bg(Color::Yellow) }
fn on_magenta(self) -> Span where Self: Sized { self.bg(Color::Magenta) }
fn on_white(self) -> Span where Self: Sized { self.bg(Color::White) }
fn on_gray(self) -> Span where Self: Sized { self.bg(Color::Gray) }
fn on_black(self) -> Span where Self: Sized { self.bg(Color::Black) }
fn rgb(self, r: u8, g: u8, b: u8) -> Span where Self: Sized { self.fg(Color::Rgb(r, g, b)) }
fn on_rgb(self, r: u8, g: u8, b: u8) -> Span where Self: Sized { self.bg(Color::Rgb(r, g, b)) }
fn hex(self, hex: &str) -> Span where Self: Sized {
self.fg(Color::hex(hex).unwrap_or(Color::White))
}
fn on_hex(self, hex: &str) -> Span where Self: Sized {
self.bg(Color::hex(hex).unwrap_or(Color::White))
}
fn bold(self) -> Span where Self: Sized;
fn italic(self) -> Span where Self: Sized;
fn underline(self) -> Span where Self: Sized;
}
impl Stylize for &str {
fn style(self, style: Style) -> Span { Span { text: self.to_string(), style } }
fn fg(self, color: Color) -> Span { Span { text: self.to_string(), style: Style::default().fg(color) } }
fn bg(self, color: Color) -> Span { Span { text: self.to_string(), style: Style::default().bg(color) } }
fn bold(self) -> Span { Span { text: self.to_string(), style: Style::default().bold() } }
fn italic(self) -> Span { Span { text: self.to_string(), style: Style::default().italic() } }
fn underline(self) -> Span { Span { text: self.to_string(), style: Style::default().underline() } }
}
impl Stylize for String {
fn style(self, style: Style) -> Span { Span { text: self, style } }
fn fg(self, color: Color) -> Span { Span { text: self, style: Style::default().fg(color) } }
fn bg(self, color: Color) -> Span { Span { text: self, style: Style::default().bg(color) } }
fn bold(self) -> Span { Span { text: self, style: Style::default().bold() } }
fn italic(self) -> Span { Span { text: self, style: Style::default().italic() } }
fn underline(self) -> Span { Span { text: self, style: Style::default().underline() } }
}
impl Stylize for Span {
fn style(mut self, style: Style) -> Span {
self.style = crate::style_parser::merge_styles(self.style, &style);
self
}
fn fg(self, color: Color) -> Span { self.style(Style::default().fg(color)) }
fn bg(self, color: Color) -> Span { self.style(Style::default().bg(color)) }
fn bold(self) -> Span { self.style(Style::default().bold()) }
fn italic(self) -> Span { self.style(Style::default().italic()) }
fn underline(self) -> Span { self.style(Style::default().underline()) }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_red() {
let s = "hello".red();
assert_eq!(s.text, "hello");
assert_eq!(s.style.fg, Some(Color::Red));
}
#[test]
fn test_red_bold() {
let s = "hello".red().bold();
assert_eq!(s.text, "hello");
assert_eq!(s.style.fg, Some(Color::Red));
assert!(s.style.bold);
}
#[test]
fn test_on_blue_white() {
let s = "text".on_blue().white();
assert_eq!(s.style.bg, Some(Color::Blue));
assert_eq!(s.style.fg, Some(Color::White));
}
#[test]
fn test_chained_style() {
let s = "x".red().on_black().bold().italic();
assert_eq!(s.style.fg, Some(Color::Red));
assert_eq!(s.style.bg, Some(Color::Black));
assert!(s.style.bold);
assert!(s.style.italic);
}
#[test]
fn test_string_impl() {
let s = String::from("hi").green();
assert_eq!(s.text, "hi");
assert_eq!(s.style.fg, Some(Color::Green));
}
#[test]
fn test_gray() {
let s = "dim".gray();
assert_eq!(s.style.fg, Some(Color::Gray));
}
#[test]
fn test_bg_methods() {
let s = "x".on_red().on_green();
assert_eq!(s.style.bg, Some(Color::Green));
}
}