1use core::fmt::{Display, Formatter, Result};
2
3use crate::{
4 Effect, GetEffects, Style, UnderlineEffect,
5 impl_macros::{
6 additive_styling::impl_additive_styling_methods,
7 composed_styling::impl_composed_styling_methods,
8 },
9 prelude::Color,
10};
11
12#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
14pub struct Styled<C: Display> {
15 content: C,
16 style: Style,
17}
18
19impl<C: Display> Styled<C> {
20 #[must_use]
22 pub const fn new(content: C) -> Self {
23 Self {
24 content,
25 style: Style::new(),
26 }
27 }
28
29 #[must_use]
31 pub const fn get_content(&self) -> &C {
32 &self.content
33 }
34
35 #[must_use]
37 pub const fn with_content<C2: Display>(&self, content: C2) -> Styled<C2> {
38 Styled {
39 content,
40 style: self.style,
41 }
42 }
43
44 #[must_use]
46 pub fn into_content(self) -> C {
47 self.content
48 }
49
50 #[must_use]
52 pub const fn get_style(&self) -> Style {
53 self.style
54 }
55
56 #[must_use]
58 pub fn with_style(self, style: Style) -> Styled<C> {
59 Self { style, ..self }
60 }
61
62 impl_additive_styling_methods! {
63 type ComposedStyling = Styled<C>;
64 args: [self];
65 to_composed_styling: { self }
66 }
67
68 impl_composed_styling_methods! {
69 args: [self, effect, underline_effect, target, color, value];
70 example_variable: r"styled";
71
72 set_effect: {
73 self.modify_style(|style| style.set_effect(effect, value))
74 }
75
76 get_effect: {
77 self.style.get_effect(effect)
78 }
79
80 get_effects: {
81 self.style.get_effects()
82 }
83
84 set_underline_effect: {
85 self.modify_style(|style| style.set_underline_effect(underline_effect))
86 }
87
88 get_underline_effect: {
89 self.style.get_underline_effect()
90 }
91
92 set_color: {
93 self.modify_style(|style| style.set_color(target, color))
94 }
95
96 get_color: {
97 self.style.get_color(target)
98 }
99 }
100
101 #[must_use]
102 fn modify_style(self, f: impl FnOnce(Style) -> Style) -> Self {
103 let style = f(self.style);
104 Self { style, ..self }
105 }
106}
107
108impl<C: Display> Display for Styled<C> {
109 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
110 if self.style == Style::default() {
111 write!(f, "{}", self.content)
112 } else {
113 let start = self.style;
114 let end = Style::default();
115 write!(f, "{start}{}{end}", self.content)
116 }
117 }
118}