annotate_snippets/renderer/
mod.rs1mod display_list;
14mod margin;
15mod styled_buffer;
16pub(crate) mod stylesheet;
17
18use crate::snippet::Message;
19pub use anstyle::*;
20use display_list::DisplayList;
21use margin::Margin;
22use std::fmt::Display;
23use stylesheet::Stylesheet;
24
25pub const DEFAULT_TERM_WIDTH: usize = 140;
26
27#[derive(Clone, Debug)]
29pub struct Renderer {
30 anonymized_line_numbers: bool,
31 term_width: usize,
32 stylesheet: Stylesheet,
33}
34
35impl Renderer {
36 pub const fn plain() -> Self {
38 Self {
39 anonymized_line_numbers: false,
40 term_width: DEFAULT_TERM_WIDTH,
41 stylesheet: Stylesheet::plain(),
42 }
43 }
44
45 pub const fn styled() -> Self {
50 const USE_WINDOWS_COLORS: bool = cfg!(windows) && !cfg!(feature = "testing-colors");
51 const BRIGHT_BLUE: Style = if USE_WINDOWS_COLORS {
52 AnsiColor::BrightCyan.on_default()
53 } else {
54 AnsiColor::BrightBlue.on_default()
55 };
56 Self {
57 stylesheet: Stylesheet {
58 error: AnsiColor::BrightRed.on_default().effects(Effects::BOLD),
59 warning: if USE_WINDOWS_COLORS {
60 AnsiColor::BrightYellow.on_default()
61 } else {
62 AnsiColor::Yellow.on_default()
63 }
64 .effects(Effects::BOLD),
65 info: BRIGHT_BLUE.effects(Effects::BOLD),
66 note: AnsiColor::BrightGreen.on_default().effects(Effects::BOLD),
67 help: AnsiColor::BrightCyan.on_default().effects(Effects::BOLD),
68 line_no: BRIGHT_BLUE.effects(Effects::BOLD),
69 emphasis: if USE_WINDOWS_COLORS {
70 AnsiColor::BrightWhite.on_default()
71 } else {
72 Style::new()
73 }
74 .effects(Effects::BOLD),
75 none: Style::new(),
76 },
77 ..Self::plain()
78 }
79 }
80
81 pub const fn anonymized_line_numbers(mut self, anonymized_line_numbers: bool) -> Self {
96 self.anonymized_line_numbers = anonymized_line_numbers;
97 self
98 }
99
100 pub const fn term_width(mut self, term_width: usize) -> Self {
102 self.term_width = term_width;
103 self
104 }
105
106 pub const fn error(mut self, style: Style) -> Self {
108 self.stylesheet.error = style;
109 self
110 }
111
112 pub const fn warning(mut self, style: Style) -> Self {
114 self.stylesheet.warning = style;
115 self
116 }
117
118 pub const fn info(mut self, style: Style) -> Self {
120 self.stylesheet.info = style;
121 self
122 }
123
124 pub const fn note(mut self, style: Style) -> Self {
126 self.stylesheet.note = style;
127 self
128 }
129
130 pub const fn help(mut self, style: Style) -> Self {
132 self.stylesheet.help = style;
133 self
134 }
135
136 pub const fn line_no(mut self, style: Style) -> Self {
138 self.stylesheet.line_no = style;
139 self
140 }
141
142 pub const fn emphasis(mut self, style: Style) -> Self {
144 self.stylesheet.emphasis = style;
145 self
146 }
147
148 pub const fn none(mut self, style: Style) -> Self {
150 self.stylesheet.none = style;
151 self
152 }
153
154 pub fn render<'a>(&'a self, msg: Message<'a>) -> impl Display + 'a {
156 DisplayList::new(
157 msg,
158 &self.stylesheet,
159 self.anonymized_line_numbers,
160 self.term_width,
161 )
162 }
163}