use {
crate::{errors::Result, styled_char::StyledChar},
crossterm::{
QueueableCommand,
style::{
Attribute,
Attributes,
Color,
ContentStyle,
PrintStyledContent,
SetBackgroundColor,
SetForegroundColor,
StyledContent,
},
},
std::fmt::{self, Display},
};
#[derive(Default, Clone)]
pub struct CompoundStyle {
pub object_style: ContentStyle, }
impl From<ContentStyle> for CompoundStyle {
fn from(object_style: ContentStyle) -> CompoundStyle {
CompoundStyle { object_style }
}
}
impl CompoundStyle {
pub fn apply_to<D>(&self, val: D) -> StyledContent<D>
where
D: Clone + Display,
{
self.object_style.clone().apply(val)
}
pub fn new(
foreground_color: Option<Color>,
background_color: Option<Color>,
attributes: Attributes,
) -> CompoundStyle {
CompoundStyle {
object_style: ContentStyle {
foreground_color,
background_color,
attributes,
},
}
}
pub fn with_fgbg(fg: Color, bg: Color) -> CompoundStyle {
CompoundStyle {
object_style: ContentStyle::new().foreground(fg).background(bg),
}
}
pub fn with_fg(fg: Color) -> CompoundStyle {
CompoundStyle {
object_style: ContentStyle::new().foreground(fg),
}
}
pub fn with_bg(bg: Color) -> CompoundStyle {
CompoundStyle {
object_style: ContentStyle::new().background(bg),
}
}
pub fn with_attr(attr: Attribute) -> CompoundStyle {
let mut cp = CompoundStyle::default();
cp.add_attr(attr);
cp
}
pub fn set_fg(&mut self, color: Color) {
self.object_style.foreground_color = Some(color);
}
pub fn set_bg(&mut self, color: Color) {
self.object_style.background_color = Some(color);
}
pub fn set_fgbg(&mut self, fg: Color, bg: Color) {
self.object_style.foreground_color = Some(fg);
self.object_style.background_color = Some(bg);
}
pub fn add_attr(&mut self, attr: Attribute) {
self.object_style.attributes.set(attr);
}
pub fn overwrite_with(&mut self, other: &CompoundStyle) {
self.object_style.foreground_color = other
.object_style
.foreground_color
.or(self.object_style.foreground_color);
self.object_style.background_color = other
.object_style
.background_color
.or(self.object_style.background_color);
self.object_style
.attributes
.extend(other.object_style.attributes);
}
#[inline(always)]
pub fn get_fg(&self) -> Option<Color> {
self.object_style.foreground_color
}
#[inline(always)]
pub fn get_bg(&self) -> Option<Color> {
self.object_style.background_color
}
#[inline(always)]
pub fn repeat_string(&self, f: &mut fmt::Formatter<'_>, s: &str, count: usize) -> fmt::Result {
if count > 0 {
write!(f, "{}", self.apply_to(s.repeat(count)))
} else {
Ok(())
}
}
#[inline(always)]
pub fn repeat_space(&self, f: &mut fmt::Formatter<'_>, count: usize) -> fmt::Result {
self.repeat_string(f, " ", count)
}
pub fn queue<W, D>(&self, w: &mut W, val: D) -> Result<()>
where
D: Clone + Display,
W: std::io::Write,
{
w.queue(PrintStyledContent(self.apply_to(val)))?;
Ok(())
}
pub fn queue_str<W>(&self, w: &mut W, s: &str) -> Result<()>
where
W: std::io::Write,
{
self.queue(w, s.to_string())
}
pub fn queue_fg<W>(&self, w: &mut W) -> Result<()>
where
W: std::io::Write,
{
if let Some(fg) = self.object_style.foreground_color {
w.queue(SetForegroundColor(fg))?;
}
Ok(())
}
pub fn queue_bg<W>(&self, w: &mut W) -> Result<()>
where
W: std::io::Write,
{
if let Some(bg) = self.object_style.background_color {
w.queue(SetBackgroundColor(bg))?;
}
Ok(())
}
pub fn style_char(&self, nude_char: char) -> StyledChar {
StyledChar::new(self.clone(), nude_char)
}
}