1e73685ebSopenharmony_ciuse termcolor::{Color, ColorSpec}; 2e73685ebSopenharmony_ci 3e73685ebSopenharmony_ciuse crate::diagnostic::{LabelStyle, Severity}; 4e73685ebSopenharmony_ci 5e73685ebSopenharmony_ci/// Configures how a diagnostic is rendered. 6e73685ebSopenharmony_ci#[derive(Clone, Debug)] 7e73685ebSopenharmony_cipub struct Config { 8e73685ebSopenharmony_ci /// The display style to use when rendering diagnostics. 9e73685ebSopenharmony_ci /// Defaults to: [`DisplayStyle::Rich`]. 10e73685ebSopenharmony_ci /// 11e73685ebSopenharmony_ci /// [`DisplayStyle::Rich`]: DisplayStyle::Rich 12e73685ebSopenharmony_ci pub display_style: DisplayStyle, 13e73685ebSopenharmony_ci /// Column width of tabs. 14e73685ebSopenharmony_ci /// Defaults to: `4`. 15e73685ebSopenharmony_ci pub tab_width: usize, 16e73685ebSopenharmony_ci /// Styles to use when rendering the diagnostic. 17e73685ebSopenharmony_ci pub styles: Styles, 18e73685ebSopenharmony_ci /// Characters to use when rendering the diagnostic. 19e73685ebSopenharmony_ci pub chars: Chars, 20e73685ebSopenharmony_ci /// The minimum number of lines to be shown after the line on which a multiline [`Label`] begins. 21e73685ebSopenharmony_ci /// 22e73685ebSopenharmony_ci /// Defaults to: `3`. 23e73685ebSopenharmony_ci pub start_context_lines: usize, 24e73685ebSopenharmony_ci /// The minimum number of lines to be shown before the line on which a multiline [`Label`] ends. 25e73685ebSopenharmony_ci /// 26e73685ebSopenharmony_ci /// Defaults to: `1`. 27e73685ebSopenharmony_ci pub end_context_lines: usize, 28e73685ebSopenharmony_ci} 29e73685ebSopenharmony_ci 30e73685ebSopenharmony_ciimpl Default for Config { 31e73685ebSopenharmony_ci fn default() -> Config { 32e73685ebSopenharmony_ci Config { 33e73685ebSopenharmony_ci display_style: DisplayStyle::Rich, 34e73685ebSopenharmony_ci tab_width: 4, 35e73685ebSopenharmony_ci styles: Styles::default(), 36e73685ebSopenharmony_ci chars: Chars::default(), 37e73685ebSopenharmony_ci start_context_lines: 3, 38e73685ebSopenharmony_ci end_context_lines: 1, 39e73685ebSopenharmony_ci } 40e73685ebSopenharmony_ci } 41e73685ebSopenharmony_ci} 42e73685ebSopenharmony_ci 43e73685ebSopenharmony_ci/// The display style to use when rendering diagnostics. 44e73685ebSopenharmony_ci#[derive(Clone, Debug)] 45e73685ebSopenharmony_cipub enum DisplayStyle { 46e73685ebSopenharmony_ci /// Output a richly formatted diagnostic, with source code previews. 47e73685ebSopenharmony_ci /// 48e73685ebSopenharmony_ci /// ```text 49e73685ebSopenharmony_ci /// error[E0001]: unexpected type in `+` application 50e73685ebSopenharmony_ci /// ┌─ test:2:9 51e73685ebSopenharmony_ci /// │ 52e73685ebSopenharmony_ci /// 2 │ (+ test "") 53e73685ebSopenharmony_ci /// │ ^^ expected `Int` but found `String` 54e73685ebSopenharmony_ci /// │ 55e73685ebSopenharmony_ci /// = expected type `Int` 56e73685ebSopenharmony_ci /// found type `String` 57e73685ebSopenharmony_ci /// 58e73685ebSopenharmony_ci /// error[E0002]: Bad config found 59e73685ebSopenharmony_ci /// 60e73685ebSopenharmony_ci /// ``` 61e73685ebSopenharmony_ci Rich, 62e73685ebSopenharmony_ci /// Output a condensed diagnostic, with a line number, severity, message and notes (if any). 63e73685ebSopenharmony_ci /// 64e73685ebSopenharmony_ci /// ```text 65e73685ebSopenharmony_ci /// test:2:9: error[E0001]: unexpected type in `+` application 66e73685ebSopenharmony_ci /// = expected type `Int` 67e73685ebSopenharmony_ci /// found type `String` 68e73685ebSopenharmony_ci /// 69e73685ebSopenharmony_ci /// error[E0002]: Bad config found 70e73685ebSopenharmony_ci /// ``` 71e73685ebSopenharmony_ci Medium, 72e73685ebSopenharmony_ci /// Output a short diagnostic, with a line number, severity, and message. 73e73685ebSopenharmony_ci /// 74e73685ebSopenharmony_ci /// ```text 75e73685ebSopenharmony_ci /// test:2:9: error[E0001]: unexpected type in `+` application 76e73685ebSopenharmony_ci /// error[E0002]: Bad config found 77e73685ebSopenharmony_ci /// ``` 78e73685ebSopenharmony_ci Short, 79e73685ebSopenharmony_ci} 80e73685ebSopenharmony_ci 81e73685ebSopenharmony_ci/// Styles to use when rendering the diagnostic. 82e73685ebSopenharmony_ci#[derive(Clone, Debug)] 83e73685ebSopenharmony_cipub struct Styles { 84e73685ebSopenharmony_ci /// The style to use when rendering bug headers. 85e73685ebSopenharmony_ci /// Defaults to `fg:red bold intense`. 86e73685ebSopenharmony_ci pub header_bug: ColorSpec, 87e73685ebSopenharmony_ci /// The style to use when rendering error headers. 88e73685ebSopenharmony_ci /// Defaults to `fg:red bold intense`. 89e73685ebSopenharmony_ci pub header_error: ColorSpec, 90e73685ebSopenharmony_ci /// The style to use when rendering warning headers. 91e73685ebSopenharmony_ci /// Defaults to `fg:yellow bold intense`. 92e73685ebSopenharmony_ci pub header_warning: ColorSpec, 93e73685ebSopenharmony_ci /// The style to use when rendering note headers. 94e73685ebSopenharmony_ci /// Defaults to `fg:green bold intense`. 95e73685ebSopenharmony_ci pub header_note: ColorSpec, 96e73685ebSopenharmony_ci /// The style to use when rendering help headers. 97e73685ebSopenharmony_ci /// Defaults to `fg:cyan bold intense`. 98e73685ebSopenharmony_ci pub header_help: ColorSpec, 99e73685ebSopenharmony_ci /// The style to use when the main diagnostic message. 100e73685ebSopenharmony_ci /// Defaults to `bold intense`. 101e73685ebSopenharmony_ci pub header_message: ColorSpec, 102e73685ebSopenharmony_ci 103e73685ebSopenharmony_ci /// The style to use when rendering bug labels. 104e73685ebSopenharmony_ci /// Defaults to `fg:red`. 105e73685ebSopenharmony_ci pub primary_label_bug: ColorSpec, 106e73685ebSopenharmony_ci /// The style to use when rendering error labels. 107e73685ebSopenharmony_ci /// Defaults to `fg:red`. 108e73685ebSopenharmony_ci pub primary_label_error: ColorSpec, 109e73685ebSopenharmony_ci /// The style to use when rendering warning labels. 110e73685ebSopenharmony_ci /// Defaults to `fg:yellow`. 111e73685ebSopenharmony_ci pub primary_label_warning: ColorSpec, 112e73685ebSopenharmony_ci /// The style to use when rendering note labels. 113e73685ebSopenharmony_ci /// Defaults to `fg:green`. 114e73685ebSopenharmony_ci pub primary_label_note: ColorSpec, 115e73685ebSopenharmony_ci /// The style to use when rendering help labels. 116e73685ebSopenharmony_ci /// Defaults to `fg:cyan`. 117e73685ebSopenharmony_ci pub primary_label_help: ColorSpec, 118e73685ebSopenharmony_ci /// The style to use when rendering secondary labels. 119e73685ebSopenharmony_ci /// Defaults `fg:blue` (or `fg:cyan` on windows). 120e73685ebSopenharmony_ci pub secondary_label: ColorSpec, 121e73685ebSopenharmony_ci 122e73685ebSopenharmony_ci /// The style to use when rendering the line numbers. 123e73685ebSopenharmony_ci /// Defaults `fg:blue` (or `fg:cyan` on windows). 124e73685ebSopenharmony_ci pub line_number: ColorSpec, 125e73685ebSopenharmony_ci /// The style to use when rendering the source code borders. 126e73685ebSopenharmony_ci /// Defaults `fg:blue` (or `fg:cyan` on windows). 127e73685ebSopenharmony_ci pub source_border: ColorSpec, 128e73685ebSopenharmony_ci /// The style to use when rendering the note bullets. 129e73685ebSopenharmony_ci /// Defaults `fg:blue` (or `fg:cyan` on windows). 130e73685ebSopenharmony_ci pub note_bullet: ColorSpec, 131e73685ebSopenharmony_ci} 132e73685ebSopenharmony_ci 133e73685ebSopenharmony_ciimpl Styles { 134e73685ebSopenharmony_ci /// The style used to mark a header at a given severity. 135e73685ebSopenharmony_ci pub fn header(&self, severity: Severity) -> &ColorSpec { 136e73685ebSopenharmony_ci match severity { 137e73685ebSopenharmony_ci Severity::Bug => &self.header_bug, 138e73685ebSopenharmony_ci Severity::Error => &self.header_error, 139e73685ebSopenharmony_ci Severity::Warning => &self.header_warning, 140e73685ebSopenharmony_ci Severity::Note => &self.header_note, 141e73685ebSopenharmony_ci Severity::Help => &self.header_help, 142e73685ebSopenharmony_ci } 143e73685ebSopenharmony_ci } 144e73685ebSopenharmony_ci 145e73685ebSopenharmony_ci /// The style used to mark a primary or secondary label at a given severity. 146e73685ebSopenharmony_ci pub fn label(&self, severity: Severity, label_style: LabelStyle) -> &ColorSpec { 147e73685ebSopenharmony_ci match (label_style, severity) { 148e73685ebSopenharmony_ci (LabelStyle::Primary, Severity::Bug) => &self.primary_label_bug, 149e73685ebSopenharmony_ci (LabelStyle::Primary, Severity::Error) => &self.primary_label_error, 150e73685ebSopenharmony_ci (LabelStyle::Primary, Severity::Warning) => &self.primary_label_warning, 151e73685ebSopenharmony_ci (LabelStyle::Primary, Severity::Note) => &self.primary_label_note, 152e73685ebSopenharmony_ci (LabelStyle::Primary, Severity::Help) => &self.primary_label_help, 153e73685ebSopenharmony_ci (LabelStyle::Secondary, _) => &self.secondary_label, 154e73685ebSopenharmony_ci } 155e73685ebSopenharmony_ci } 156e73685ebSopenharmony_ci 157e73685ebSopenharmony_ci #[doc(hidden)] 158e73685ebSopenharmony_ci pub fn with_blue(blue: Color) -> Styles { 159e73685ebSopenharmony_ci let header = ColorSpec::new().set_bold(true).set_intense(true).clone(); 160e73685ebSopenharmony_ci 161e73685ebSopenharmony_ci Styles { 162e73685ebSopenharmony_ci header_bug: header.clone().set_fg(Some(Color::Red)).clone(), 163e73685ebSopenharmony_ci header_error: header.clone().set_fg(Some(Color::Red)).clone(), 164e73685ebSopenharmony_ci header_warning: header.clone().set_fg(Some(Color::Yellow)).clone(), 165e73685ebSopenharmony_ci header_note: header.clone().set_fg(Some(Color::Green)).clone(), 166e73685ebSopenharmony_ci header_help: header.clone().set_fg(Some(Color::Cyan)).clone(), 167e73685ebSopenharmony_ci header_message: header, 168e73685ebSopenharmony_ci 169e73685ebSopenharmony_ci primary_label_bug: ColorSpec::new().set_fg(Some(Color::Red)).clone(), 170e73685ebSopenharmony_ci primary_label_error: ColorSpec::new().set_fg(Some(Color::Red)).clone(), 171e73685ebSopenharmony_ci primary_label_warning: ColorSpec::new().set_fg(Some(Color::Yellow)).clone(), 172e73685ebSopenharmony_ci primary_label_note: ColorSpec::new().set_fg(Some(Color::Green)).clone(), 173e73685ebSopenharmony_ci primary_label_help: ColorSpec::new().set_fg(Some(Color::Cyan)).clone(), 174e73685ebSopenharmony_ci secondary_label: ColorSpec::new().set_fg(Some(blue)).clone(), 175e73685ebSopenharmony_ci 176e73685ebSopenharmony_ci line_number: ColorSpec::new().set_fg(Some(blue)).clone(), 177e73685ebSopenharmony_ci source_border: ColorSpec::new().set_fg(Some(blue)).clone(), 178e73685ebSopenharmony_ci note_bullet: ColorSpec::new().set_fg(Some(blue)).clone(), 179e73685ebSopenharmony_ci } 180e73685ebSopenharmony_ci } 181e73685ebSopenharmony_ci} 182e73685ebSopenharmony_ci 183e73685ebSopenharmony_ciimpl Default for Styles { 184e73685ebSopenharmony_ci fn default() -> Styles { 185e73685ebSopenharmony_ci // Blue is really difficult to see on the standard windows command line 186e73685ebSopenharmony_ci #[cfg(windows)] 187e73685ebSopenharmony_ci const BLUE: Color = Color::Cyan; 188e73685ebSopenharmony_ci #[cfg(not(windows))] 189e73685ebSopenharmony_ci const BLUE: Color = Color::Blue; 190e73685ebSopenharmony_ci 191e73685ebSopenharmony_ci Self::with_blue(BLUE) 192e73685ebSopenharmony_ci } 193e73685ebSopenharmony_ci} 194e73685ebSopenharmony_ci 195e73685ebSopenharmony_ci/// Characters to use when rendering the diagnostic. 196e73685ebSopenharmony_ci#[derive(Clone, Debug)] 197e73685ebSopenharmony_cipub struct Chars { 198e73685ebSopenharmony_ci /// The character to use for the top-left border of the source. 199e73685ebSopenharmony_ci /// Defaults to: `'┌'`. 200e73685ebSopenharmony_ci pub source_border_top_left: char, 201e73685ebSopenharmony_ci /// The character to use for the top border of the source. 202e73685ebSopenharmony_ci /// Defaults to: `'─'`. 203e73685ebSopenharmony_ci pub source_border_top: char, 204e73685ebSopenharmony_ci /// The character to use for the left border of the source. 205e73685ebSopenharmony_ci /// Defaults to: `'│'`. 206e73685ebSopenharmony_ci pub source_border_left: char, 207e73685ebSopenharmony_ci /// The character to use for the left border break of the source. 208e73685ebSopenharmony_ci /// Defaults to: `'·'`. 209e73685ebSopenharmony_ci pub source_border_left_break: char, 210e73685ebSopenharmony_ci 211e73685ebSopenharmony_ci /// The character to use for the note bullet. 212e73685ebSopenharmony_ci /// Defaults to: `'='`. 213e73685ebSopenharmony_ci pub note_bullet: char, 214e73685ebSopenharmony_ci 215e73685ebSopenharmony_ci /// The character to use for marking a single-line primary label. 216e73685ebSopenharmony_ci /// Defaults to: `'^'`. 217e73685ebSopenharmony_ci pub single_primary_caret: char, 218e73685ebSopenharmony_ci /// The character to use for marking a single-line secondary label. 219e73685ebSopenharmony_ci /// Defaults to: `'-'`. 220e73685ebSopenharmony_ci pub single_secondary_caret: char, 221e73685ebSopenharmony_ci 222e73685ebSopenharmony_ci /// The character to use for marking the start of a multi-line primary label. 223e73685ebSopenharmony_ci /// Defaults to: `'^'`. 224e73685ebSopenharmony_ci pub multi_primary_caret_start: char, 225e73685ebSopenharmony_ci /// The character to use for marking the end of a multi-line primary label. 226e73685ebSopenharmony_ci /// Defaults to: `'^'`. 227e73685ebSopenharmony_ci pub multi_primary_caret_end: char, 228e73685ebSopenharmony_ci /// The character to use for marking the start of a multi-line secondary label. 229e73685ebSopenharmony_ci /// Defaults to: `'\''`. 230e73685ebSopenharmony_ci pub multi_secondary_caret_start: char, 231e73685ebSopenharmony_ci /// The character to use for marking the end of a multi-line secondary label. 232e73685ebSopenharmony_ci /// Defaults to: `'\''`. 233e73685ebSopenharmony_ci pub multi_secondary_caret_end: char, 234e73685ebSopenharmony_ci /// The character to use for the top-left corner of a multi-line label. 235e73685ebSopenharmony_ci /// Defaults to: `'╭'`. 236e73685ebSopenharmony_ci pub multi_top_left: char, 237e73685ebSopenharmony_ci /// The character to use for the top of a multi-line label. 238e73685ebSopenharmony_ci /// Defaults to: `'─'`. 239e73685ebSopenharmony_ci pub multi_top: char, 240e73685ebSopenharmony_ci /// The character to use for the bottom-left corner of a multi-line label. 241e73685ebSopenharmony_ci /// Defaults to: `'╰'`. 242e73685ebSopenharmony_ci pub multi_bottom_left: char, 243e73685ebSopenharmony_ci /// The character to use when marking the bottom of a multi-line label. 244e73685ebSopenharmony_ci /// Defaults to: `'─'`. 245e73685ebSopenharmony_ci pub multi_bottom: char, 246e73685ebSopenharmony_ci /// The character to use for the left of a multi-line label. 247e73685ebSopenharmony_ci /// Defaults to: `'│'`. 248e73685ebSopenharmony_ci pub multi_left: char, 249e73685ebSopenharmony_ci 250e73685ebSopenharmony_ci /// The character to use for the left of a pointer underneath a caret. 251e73685ebSopenharmony_ci /// Defaults to: `'│'`. 252e73685ebSopenharmony_ci pub pointer_left: char, 253e73685ebSopenharmony_ci} 254e73685ebSopenharmony_ci 255e73685ebSopenharmony_ciimpl Default for Chars { 256e73685ebSopenharmony_ci fn default() -> Chars { 257e73685ebSopenharmony_ci Chars { 258e73685ebSopenharmony_ci source_border_top_left: '┌', 259e73685ebSopenharmony_ci source_border_top: '─', 260e73685ebSopenharmony_ci source_border_left: '│', 261e73685ebSopenharmony_ci source_border_left_break: '·', 262e73685ebSopenharmony_ci 263e73685ebSopenharmony_ci note_bullet: '=', 264e73685ebSopenharmony_ci 265e73685ebSopenharmony_ci single_primary_caret: '^', 266e73685ebSopenharmony_ci single_secondary_caret: '-', 267e73685ebSopenharmony_ci 268e73685ebSopenharmony_ci multi_primary_caret_start: '^', 269e73685ebSopenharmony_ci multi_primary_caret_end: '^', 270e73685ebSopenharmony_ci multi_secondary_caret_start: '\'', 271e73685ebSopenharmony_ci multi_secondary_caret_end: '\'', 272e73685ebSopenharmony_ci multi_top_left: '╭', 273e73685ebSopenharmony_ci multi_top: '─', 274e73685ebSopenharmony_ci multi_bottom_left: '╰', 275e73685ebSopenharmony_ci multi_bottom: '─', 276e73685ebSopenharmony_ci multi_left: '│', 277e73685ebSopenharmony_ci 278e73685ebSopenharmony_ci pointer_left: '│', 279e73685ebSopenharmony_ci } 280e73685ebSopenharmony_ci } 281e73685ebSopenharmony_ci} 282