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}