use crate::text::{Color, Intensity};
use crossterm::style::{Attribute, Attributes};
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Weight {
Normal,
Bold,
Thin,
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Appearance {
attributes: Attributes,
weight: Weight,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct TextStyle {
background: Color,
foreground: Color,
appearance: Appearance,
}
impl Default for Weight {
fn default() -> Self {
Weight::Normal
}
}
impl Weight {
fn attribute(self) -> Option<Attribute> {
match self {
Weight::Bold => Some(Attribute::Bold),
Weight::Thin => Some(Attribute::Dim),
_ => None,
}
}
}
impl Appearance {
pub fn with_weight(mut self, weight: Weight) -> Self {
self.weight = weight;
self
}
pub fn with_italic(mut self, enable: bool) -> Self {
if enable {
self.attributes.set(Attribute::Italic);
} else {
self.attributes.unset(Attribute::Italic);
}
self
}
pub fn with_strikethrough(mut self, enable: bool) -> Self {
if enable {
self.attributes.set(Attribute::CrossedOut);
} else {
self.attributes.unset(Attribute::CrossedOut);
}
self
}
pub fn with_underline(mut self, enable: bool) -> Self {
if enable {
self.attributes.set(Attribute::Underlined);
} else {
self.attributes.unset(Attribute::Underlined);
}
self
}
pub fn with_reverse(mut self, enable: bool) -> Self {
if enable {
self.attributes.set(Attribute::Reverse);
} else {
self.attributes.unset(Attribute::Reverse);
}
self
}
pub(crate) fn changed(&self, before: Self) -> Attributes {
let mut attr = self.attributes;
if self.weight != before.weight {
match self.weight.attribute() {
Some(w) => attr.set(w),
None => attr.set(Attribute::NormalIntensity),
}
}
if before.attributes.has(Attribute::Italic) {
attr.set(Attribute::NoItalic);
}
if before.attributes.has(Attribute::CrossedOut) {
attr.set(Attribute::NotCrossedOut);
}
if before.attributes.has(Attribute::Underlined) {
attr.set(Attribute::NoUnderline);
}
if before.attributes.has(Attribute::Reverse) {
attr.set(Attribute::NoReverse);
}
attr
}
}
impl Default for TextStyle {
fn default() -> Self {
let background = Color::Black(Intensity::Normal);
let foreground = Color::White(Intensity::Bright);
let appearance = Appearance::default();
Self {
background,
foreground,
appearance,
}
}
}
impl TextStyle {
pub fn with_background(mut self, clr: Color) -> Self {
self.background = clr;
self
}
pub fn with_foreground(mut self, clr: Color) -> Self {
self.foreground = clr;
self
}
pub fn with_appearance(mut self, app: Appearance) -> Self {
self.appearance = app;
self
}
pub fn background(&self) -> Color {
self.background
}
pub fn foreground(&self) -> Color {
self.foreground
}
pub fn appearance(&self) -> Appearance {
self.appearance
}
}