use core::fmt::{Display, Formatter, Result};
use crate::{
Effect, GetEffects, Style, UnderlineEffect,
impl_macros::{
additive_styling::impl_additive_styling_methods,
composed_styling::impl_composed_styling_methods,
},
prelude::Color,
};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
pub struct Styled<C: Display> {
content: C,
style: Style,
}
impl<C: Display> Styled<C> {
#[must_use]
pub const fn new(content: C) -> Self {
Self {
content,
style: Style::new(),
}
}
#[must_use]
pub const fn get_content(&self) -> &C {
&self.content
}
#[must_use]
pub const fn with_content<C2: Display>(&self, content: C2) -> Styled<C2> {
Styled {
content,
style: self.style,
}
}
#[must_use]
pub fn into_content(self) -> C {
self.content
}
#[must_use]
pub const fn get_style(&self) -> Style {
self.style
}
#[must_use]
pub fn with_style(self, style: Style) -> Styled<C> {
Self { style, ..self }
}
impl_additive_styling_methods! {
type ComposedStyling = Styled<C>;
args: [self];
to_composed_styling: { self }
}
impl_composed_styling_methods! {
args: [self, effect, underline_effect, target, color, value];
example_variable: r"styled";
set_effect: {
self.modify_style(|style| style.set_effect(effect, value))
}
get_effect: {
self.style.get_effect(effect)
}
get_effects: {
self.style.get_effects()
}
set_underline_effect: {
self.modify_style(|style| style.set_underline_effect(underline_effect))
}
get_underline_effect: {
self.style.get_underline_effect()
}
set_color: {
self.modify_style(|style| style.set_color(target, color))
}
get_color: {
self.style.get_color(target)
}
}
#[must_use]
fn modify_style(self, f: impl FnOnce(Style) -> Style) -> Self {
let style = f(self.style);
Self { style, ..self }
}
}
impl<C: Display> Display for Styled<C> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
if self.style == Style::default() {
write!(f, "{}", self.content)
} else {
let start = self.style;
let end = Style::default();
write!(f, "{start}{}{end}", self.content)
}
}
}