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