1 use std::fmt::Display;
2 
3 #[cfg(feature = "serde")]
4 use serde::{Deserialize, Serialize};
5 
6 use super::super::SetAttribute;
7 
8 // This macro generates the Attribute enum, its iterator
9 // function, and the static array containing the sgr code
10 // of each attribute
11 macro_rules! Attribute {
12     (
13         $(
14             $(#[$inner:ident $($args:tt)*])*
15             $name:ident = $sgr:expr,
16         )*
17     ) => {
18         /// Represents an attribute.
19         ///
20         /// # Platform-specific Notes
21         ///
22         /// * Only UNIX and Windows 10 terminals do support text attributes.
23         /// * Keep in mind that not all terminals support all attributes.
24         /// * Crossterm implements almost all attributes listed in the
25         ///   [SGR parameters](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters).
26         ///
27         /// | Attribute | Windows | UNIX | Notes |
28         /// | :-- | :--: | :--: | :-- |
29         /// | `Reset` | ✓ | ✓ | |
30         /// | `Bold` | ✓ | ✓ | |
31         /// | `Dim` | ✓ | ✓ | |
32         /// | `Italic` | ? | ? | Not widely supported, sometimes treated as inverse. |
33         /// | `Underlined` | ✓ | ✓ | |
34         /// | `SlowBlink` | ? | ? | Not widely supported, sometimes treated as inverse. |
35         /// | `RapidBlink` | ? | ? | Not widely supported. MS-DOS ANSI.SYS; 150+ per minute. |
36         /// | `Reverse` | ✓ | ✓ | |
37         /// | `Hidden` | ✓ | ✓ | Also known as Conceal. |
38         /// | `Fraktur` | ✗ | ✓ | Legible characters, but marked for deletion. |
39         /// | `DefaultForegroundColor` | ? | ? | Implementation specific (according to standard). |
40         /// | `DefaultBackgroundColor` | ? | ? | Implementation specific (according to standard). |
41         /// | `Framed` | ? | ? | Not widely supported. |
42         /// | `Encircled` | ? | ? | This should turn on the encircled attribute. |
43         /// | `OverLined` | ? | ? | This should draw a line at the top of the text. |
44         ///
45         /// # Examples
46         ///
47         /// Basic usage:
48         ///
49         /// ```no_run
50         /// use crossterm::style::Attribute;
51         ///
52         /// println!(
53         ///     "{} Underlined {} No Underline",
54         ///     Attribute::Underlined,
55         ///     Attribute::NoUnderline
56         /// );
57         /// ```
58         ///
59         /// Style existing text:
60         ///
61         /// ```no_run
62         /// use crossterm::style::Stylize;
63         ///
64         /// println!("{}", "Bold text".bold());
65         /// println!("{}", "Underlined text".underlined());
66         /// println!("{}", "Negative text".negative());
67         /// ```
68         #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
69         #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
70         pub enum Attribute {
71             $(
72                 $(#[$inner $($args)*])*
73                 $name,
74             )*
75         }
76 
77         pub static SGR: &'static[i16] = &[
78             $($sgr,)*
79         ];
80 
81         impl Attribute {
82             /// Iterates over all the variants of the Attribute enum.
83             pub fn iterator() -> impl Iterator<Item = Attribute> {
84                 use self::Attribute::*;
85                 [ $($name,)* ].iter().copied()
86             }
87         }
88     }
89 }
90 
91 #[non_exhaustive]
92 Attribute! {
93     /// Resets all the attributes.
94     Reset = 0,
95     /// Increases the text intensity.
96     Bold = 1,
97     /// Decreases the text intensity.
98     Dim = 2,
99     /// Emphasises the text.
100     Italic = 3,
101     /// Underlines the text.
102     Underlined = 4,
103     /// Makes the text blinking (< 150 per minute).
104     SlowBlink = 5,
105     /// Makes the text blinking (>= 150 per minute).
106     RapidBlink = 6,
107     /// Swaps foreground and background colors.
108     Reverse = 7,
109     /// Hides the text (also known as Conceal).
110     Hidden = 8,
111     /// Crosses the text.
112     CrossedOut = 9,
113     /// Sets the [Fraktur](https://en.wikipedia.org/wiki/Fraktur) typeface.
114     ///
115     /// Mostly used for [mathematical alphanumeric symbols](https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols).
116     Fraktur = 20,
117     /// Turns off the `Bold` attribute. - Inconsistent - Prefer to use NormalIntensity
118     NoBold = 21,
119     /// Switches the text back to normal intensity (no bold, italic).
120     NormalIntensity = 22,
121     /// Turns off the `Italic` attribute.
122     NoItalic = 23,
123     /// Turns off the `Underlined` attribute.
124     NoUnderline = 24,
125     /// Turns off the text blinking (`SlowBlink` or `RapidBlink`).
126     NoBlink = 25,
127     /// Turns off the `Reverse` attribute.
128     NoReverse = 27,
129     /// Turns off the `Hidden` attribute.
130     NoHidden = 28,
131     /// Turns off the `CrossedOut` attribute.
132     NotCrossedOut = 29,
133     /// Makes the text framed.
134     Framed = 51,
135     /// Makes the text encircled.
136     Encircled = 52,
137     /// Draws a line at the top of the text.
138     OverLined = 53,
139     /// Turns off the `Frame` and `Encircled` attributes.
140     NotFramedOrEncircled = 54,
141     /// Turns off the `OverLined` attribute.
142     NotOverLined = 55,
143 }
144 
145 impl Display for Attribute {
fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>146     fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
147         write!(f, "{}", SetAttribute(*self))?;
148         Ok(())
149     }
150 }
151 
152 impl Attribute {
153     /// Returns a u32 with one bit set, which is the
154     /// signature of this attribute in the Attributes
155     /// bitset.
156     ///
157     /// The +1 enables storing Reset (whose index is 0)
158     ///  in the bitset Attributes.
159     #[inline(always)]
bytes(self) -> u32160     pub const fn bytes(self) -> u32 {
161         1 << ((self as u32) + 1)
162     }
163     /// Returns the SGR attribute value.
164     ///
165     /// See https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
sgr(self) -> i16166     pub fn sgr(self) -> i16 {
167         SGR[self as usize]
168     }
169 }
170