easy_sgr/discrete/mod.rs
1use std::fmt::Display;
2
3use crate::{EasySGR, SGRBuilder, SGRWriter};
4
5/// Implements [`FromStr`](std::str::FromStr) for the [`discrete`](crate::discrete) module
6#[cfg(feature = "from-str")]
7pub mod from_str;
8
9/// An SGR style code's end & escape
10///
11/// Intended use case is when the `partial` feature is enable
12///
13/// # Examples
14///
15/// Using it with `partial` enabled:
16///
17///```rust
18///use easy_sgr::{Color::*, Seq::*, Style::*};
19///
20///println!("{Esc}{Bold};{BlueBg}{End}This should be bold & italic!{Esc}{Reset}{End}");
21///```
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub enum Seq {
24 /// The sequence escape string, `\x1b[`
25 Esc,
26 /// The sequence end string, `m`
27 End,
28}
29impl Display for Seq {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 f.write_str(match self {
32 Self::Esc => "\x1b[",
33 Self::End => "m",
34 })
35 }
36}
37/// An SGR style code
38///
39/// # Examples
40///
41///```rust
42///use easy_sgr::Style::*;
43///
44///println!(
45///"
46///{Bold}{Italic}This text is bold & italic
47///{Underline}This text is also underline
48///{NotUnderline}Now back to bold & italic
49///{Reset}And lastly normal text"
50///);
51///```
52#[derive(Debug, Clone, PartialEq, Eq)]
53pub enum Style {
54 /// Represents the SGR code `0`
55 ///
56 /// Resets all(including color & custom codes) to the terminal's default
57 Reset,
58 /// Represents the SGR code `1`
59 Bold,
60 /// Represents the SGR code `2`
61 Dim,
62 /// Represents the SGR code `3`
63 Italic,
64 /// Represents the SGR code `4`
65 Underline,
66 /// Represents the SGR code `5`
67 Blinking,
68 /// Represents the SGR code `7`
69 Inverse,
70 /// Represents the SGR code `8`
71 Hidden,
72 /// Represents the SGR code `9`
73 Strikethrough,
74 /// Represents the SGR code `22`
75 ///
76 /// Is equivalent to [`Style::NotDim`]
77 NotBold,
78 /// Represents the SGR code `22`
79 ///
80 /// Is equivalent to [`Style::NotBold`]
81 NotDim,
82 /// Represents the SGR code `23`
83 NotItalic,
84 /// Represents the SGR code `24`
85 NotUnderline,
86 /// Represents the SGR code `25`
87 NotBlinking,
88 /// Represents the SGR code `27`
89 NotInverse,
90 /// Represents the SGR code `28`
91 NotHidden,
92 /// Represents the SGR code `29`
93 NotStrikethrough,
94}
95impl Display for Style {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 self.standard_display(f)
98 }
99}
100impl DiscreteSGR for Style {
101 fn write(&self, builder: &mut SGRBuilder) {
102 use Style::*;
103 builder.write_code(match self {
104 Reset => 0,
105 Bold => 1,
106 Dim => 2,
107 Italic => 3,
108 Underline => 4,
109 Blinking => 5,
110 Inverse => 7,
111 Hidden => 8,
112 Strikethrough => 9,
113 NotBold | NotDim => 22,
114 NotItalic => 23,
115 NotUnderline => 24,
116 NotBlinking => 25,
117 NotInverse => 27,
118 NotHidden => 28,
119 NotStrikethrough => 29,
120 });
121 }
122}
123/// An SGR color code
124///
125/// # Examples
126///
127///```rust
128///use easy_sgr::Color::*;
129///
130///println!("{RedFg}0This text color is red!");
131///println!("{BlackBg}And now its background is white");
132///println!("{DefaultBg}Now back to just red");
133///println!("{DefaultFg}Finally normal text");
134///```
135#[derive(Debug, Clone, PartialEq, Eq)]
136pub enum Color {
137 /// Represents the SGR code `30`
138 BlackFg,
139 /// Represents the SGR code `31`
140 RedFg,
141 /// Represents the SGR code `32`
142 GreenFg,
143 /// Represents the SGR code `33`
144 YellowFg,
145 /// Represents the SGR code `34`
146 BlueFg,
147 /// Represents the SGR code `35`
148 MagentaFg,
149 /// Represents the SGR code `36`
150 CyanFg,
151 /// Represents the SGR code `37`
152 WhiteFg,
153 /// Represents the SGR codes `38;5;<n>`
154 ///
155 /// Where `<n>` is an 8 bit color
156 ByteFg(u8),
157 /// Represents the SGR codes `38;2;<n1>;<n2>;<n3>`
158 ///
159 /// Where `<n1>`,`<n2>`,`<n3>` are 8 bit colors
160 RgbFg(u8, u8, u8),
161 /// Represents the SGR code `39`
162 DefaultFg,
163
164 /// Represents the SGR code `40`
165 BlackBg,
166 /// Represents the SGR code `41`
167 RedBg,
168 /// Represents the SGR code `42`
169 GreenBg,
170 /// Represents the SGR code `43`
171 YellowBg,
172 /// Represents the SGR code `44`
173 BlueBg,
174 /// Represents the SGR code `45`
175 MagentaBg,
176 /// Represents the SGR code `46`
177 CyanBg,
178 /// Represents the SGR code `47`
179 WhiteBg,
180 /// Represents the SGR codes `48;5;<n>`
181 ///
182 /// Where `<n>` is an 8 bit color
183 ByteBg(u8),
184 /// Represents the SGR codes `38;2;<n1>;<n2>;<n3>`
185 ///
186 /// Where `<n1>`,`<n2>`,`<n3>` are 8 bit colors
187 RgbBg(u8, u8, u8),
188 /// Represents the SGR code `49`
189 DefaultBg,
190}
191impl Display for Color {
192 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
193 self.standard_display(f)
194 }
195}
196impl DiscreteSGR for Color {
197 fn write(&self, builder: &mut SGRBuilder) {
198 use Color::*;
199 match self {
200 BlackFg => builder.write_code(30),
201 RedFg => builder.write_code(31),
202 GreenFg => builder.write_code(32),
203 YellowFg => builder.write_code(33),
204 BlueFg => builder.write_code(34),
205 MagentaFg => builder.write_code(35),
206 CyanFg => builder.write_code(36),
207 WhiteFg => builder.write_code(37),
208 ByteFg(n) => builder.write_codes(&[38, 5, *n]),
209 RgbFg(r, g, b) => builder.write_codes(&[38, 2, *r, *g, *b]),
210 DefaultFg => builder.write_code(39),
211
212 BlackBg => builder.write_code(40),
213 RedBg => builder.write_code(41),
214 GreenBg => builder.write_code(42),
215 YellowBg => builder.write_code(43),
216 BlueBg => builder.write_code(44),
217 MagentaBg => builder.write_code(45),
218 CyanBg => builder.write_code(46),
219 WhiteBg => builder.write_code(47),
220 ByteBg(n) => builder.write_codes(&[48, 5, *n]),
221 RgbBg(r, g, b) => builder.write_codes(&[48, 2, *r, *g, *b]),
222 DefaultBg => builder.write_code(49),
223 }
224 }
225}
226/// Represents SGR sequences that can be used discretely.
227///
228/// This means it doesn't exist in terms of a [`SGRString`](crate::SGRString),
229/// though it can be used in conjunction with one
230#[allow(clippy::module_name_repetitions)]
231pub trait DiscreteSGR: Sized + Display + EasySGR {
232 /// Writes a set of SGR codes to the given [`SGRWriter`]
233 ///
234 /// Writing is not an IO operation, instead writing
235 /// pushes codes to the [`SGRBuilder`]'s buffer
236 fn write(&self, writer: &mut SGRBuilder);
237 /// Writes an SGR sequence to the given [`Formatter`](std::fmt::Formatter)
238 ///
239 /// # Errors
240 ///
241 /// Return an error if writing to the [`Formatter`](std::fmt::Formatter) fails
242 #[inline]
243 #[cfg(not(feature = "partial"))]
244 fn standard_display(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result {
245 SGRWriter::from(f).inline_sgr(self)
246 }
247 /// Writes an SGR sequence to the given [`Formatter`](std::fmt::Formatter)
248 ///
249 /// Uses [`SGRWriter::partial_sgr`], so the sequence end & escape strings
250 /// are not written
251 ///
252 /// # Errors
253 ///
254 /// Return an error if writing to the [`Formatter`](std::fmt::Formatter) fails
255 #[inline]
256 #[cfg(feature = "partial")]
257 fn standard_display(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result {
258 SGRWriter::from(f).partial_sgr(self)
259 }
260}