1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
use crate::Style;
/// Enum representing text attributes, largely for text formatting.
///
/// Text attributes are typically applied to a [`Style`], [`Color`], or
/// [`Painted`] struct via the corresponding chainable builder methods such as
/// [`bold()`] or [`italic()`]. The returned value will apply the attribute(s)
/// when rendered or printed.
///
/// Attributes are idempotent, so applying an attribute more than once has no
/// more affect than applying it once.
///
/// # Terminal Support
///
/// Whether an applied attribute actually has an effect on how text is rendered
/// in a terminal depends on the terminal's support for the attribute as well as
/// the terminal's configuration. Common attributes, such as `bold`, `dim`,
/// `italic`, `underline`, and `strike` typically have good support and are
/// largely reliable. Less commonly supported attributes like `conceal` and
/// `invert` will _usually_ be supported by "modern" terminals. Rarely supprted
/// attributes, like `blink` and `rapid blink` will usually have no effect when
/// applied.
///
/// # Example
///
/// ```rust
/// use yansi::{Style, Color::Red};
///
/// /// A style with red foreground and every "common" attribute applied.
/// static MAD: Style = Red.bold().dim().italic().underline().strike();
/// ```
///
/// [`Style`]: crate::Style
/// [`Painted`]: crate::Painted
/// [`Color`]: crate::Painted
/// [`bold()`]: crate::Style::bold()
/// [`italic()`]: crate::Style::italic()
#[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord, Hash)]
pub enum Attribute {
/// Makes text <b>bold</b>.
///
/// Typically used via the [`bold()`](crate::Style::bold()) builder method.
Bold,
/// Makes text <span style="opacity: 50%">dim</span>.
///
/// Typically used via the [`dim()`](crate::Style::dim()) builder method.
Dim,
/// Display text in <i>italics</i>.
///
/// Typically used via the [`italic()`](crate::Style::italic()) builder
/// method.
Italic,
/// <u>Underline</u> text.
///
/// Typically used via the [`underline()`](crate::Style::underline())
/// builder method.
Underline,
/// <style>@keyframes blinker { 50% { opacity: 0; } }</style>
/// <span style="animation: blinker 1s linear infinite;">Blink.</span>
///
/// Typically used via the [`blink()`](crate::Style::blink()) builder
/// method.
Blink,
/// <style>@keyframes blinker { 50% { opacity: 0; } }</style>
/// <span style="animation: blinker 0.5s linear infinite;">Blink rapidly.</span>
///
/// Typically used via the [`rapid_blink()`](crate::Style::rapid_blink())
/// builder method.
RapidBlink,
/// <span style="background: black; color: white;">Invert</span>
/// (flip) the foreground and background colors.
///
/// Typically used via the [`invert()`](crate::Style::invert()) builder
/// method.
Invert,
/// <span style="color: #333; background: #000;">Conceal</span> text.
///
/// Typically used via the [`conceal()`](crate::Style::conceal()) builder
/// method.
Conceal,
/// Display text with a <s>strike</s> through it.
///
/// Typically used via the [`strike()`](crate::Style::strike()) builder
/// method.
Strike,
}
/// Enum representing a `yansi` quirk.
///
/// See the [crate level docs](crate#quirks) for details.
#[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord, Hash)]
pub enum Quirk {
/// Mask: omit when painting is disabled.
///
/// Typically applied via the [`mask()`](crate::Painted::mask()) builder
/// method.
///
/// See the [crate level docs](crate#masking) for details.
Mask,
/// Wrap the value: replace resets with the wrapped styling.
///
/// Typically applied via the [`wrap()`](crate::Painted::wrap()) builder
/// method.
///
/// See the [crate level docs](crate#wrapping) for details.
Wrap,
/// Linger: do not clear the style after it is applied.
///
/// Typically applied via the [`linger()`](crate::Painted::linger()) builder
/// method.
///
/// See the [crate level docs](crate#lingering) for details.
Linger,
/// Always clear styling afterwards, even if no actual styling was applied.
///
/// Overrides the [`Linger`](Quirk::Linger) quirk if present.
///
/// Typically applied via the [`clear()`](crate::Painted::clear()) builder
/// method.
Clear,
/// Brighten the foreground color if it is not already bright.
///
/// Typically applied via the [`bright()`](crate::Painted::bright()) builder
/// method.
///
/// See the [crate level docs](crate#brightening) for details.
Bright,
/// Brighten the background color if it is not already bright.
///
/// Typically applied via the [`on_bright()`](crate::Painted::on_bright())
/// builder
/// method.
///
/// See the [crate level docs](crate#brightening) for details.
OnBright,
}
set_enum! {
Attribute { Bold, Dim, Italic, Underline, Blink, RapidBlink, Invert, Conceal, Strike }
}
set_enum! {
Quirk { Mask, Wrap, Linger, Clear, Bright, OnBright }
}
impl Attribute {
pub(crate) fn fmt(&self, f: &mut dyn core::fmt::Write) -> core::fmt::Result {
write!(f, "{}", match self {
Attribute::Bold => 1,
Attribute::Dim => 2,
Attribute::Italic => 3,
Attribute::Underline => 4,
Attribute::Blink => 5,
Attribute::RapidBlink => 6,
Attribute::Invert => 7,
Attribute::Conceal => 8,
Attribute::Strike => 9,
})
}
/// Returns a `Style` with the attribute `self` enabled.
///
/// # Example
///
/// ```rust
/// use yansi::{Style, Attribute::Bold};
///
/// static EMBOLDEN: Style = Bold.style();
/// ```
pub const fn style(self) -> Style {
Style::new().attr(self)
}
}
impl Quirk {
/// Returns a `Style` with the quirk `self` enabled.
///
/// # Example
///
/// ```rust
/// use yansi::{Style, Quirk::Mask};
///
/// static MASKED: Style = Mask.style();
/// ```
pub const fn style(self) -> Style {
Style::new().quirk(self)
}
}
impl From<Attribute> for crate::Style {
fn from(attr: Attribute) -> Self {
attr.style()
}
}
impl From<Quirk> for crate::Style {
fn from(quirk: Quirk) -> Self {
quirk.style()
}
}