Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a5f00ab

Browse files
authoredNov 14, 2023
Merge pull request #66 from Muscraft/move-impls
refactor: Move impls near definitions
2 parents 88c3297 + bc59c12 commit a5f00ab

File tree

4 files changed

+1316
-1326
lines changed

4 files changed

+1316
-1326
lines changed
 

‎src/display_list/from_snippet.rs

Lines changed: 0 additions & 580 deletions
This file was deleted.

‎src/display_list/mod.rs

Lines changed: 1314 additions & 3 deletions
Large diffs are not rendered by default.

‎src/display_list/structs.rs

Lines changed: 0 additions & 308 deletions
This file was deleted.

‎src/formatter/mod.rs

Lines changed: 2 additions & 435 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,10 @@
1-
use std::{
2-
cmp,
3-
fmt::{self, Display, Write},
4-
iter::once,
5-
};
6-
71
pub mod style;
82

9-
use self::style::{Style, StyleClass, Stylesheet};
3+
use self::style::Stylesheet;
104

115
#[cfg(feature = "color")]
126
use crate::stylesheets::color::AnsiTermStylesheet;
13-
use crate::{display_list::*, stylesheets::no_color::NoColorStylesheet};
14-
15-
fn format_repeat_char(c: char, n: usize, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16-
for _ in 0..n {
17-
f.write_char(c)?;
18-
}
19-
Ok(())
20-
}
21-
22-
#[inline]
23-
fn is_annotation_empty(annotation: &Annotation<'_>) -> bool {
24-
annotation
25-
.label
26-
.iter()
27-
.all(|fragment| fragment.content.is_empty())
28-
}
7+
use crate::stylesheets::no_color::NoColorStylesheet;
298

309
#[cfg(feature = "color")]
3110
#[inline]
@@ -42,415 +21,3 @@ pub fn get_term_style(color: bool) -> Box<dyn Stylesheet> {
4221
pub fn get_term_style(_color: bool) -> Box<dyn Stylesheet> {
4322
Box::new(NoColorStylesheet)
4423
}
45-
46-
impl<'a> fmt::Display for DisplayList<'a> {
47-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48-
let lineno_width = self.body.iter().fold(0, |max, line| match line {
49-
DisplayLine::Source {
50-
lineno: Some(lineno),
51-
..
52-
} => {
53-
// The largest line is the largest width.
54-
cmp::max(*lineno, max)
55-
}
56-
_ => max,
57-
});
58-
let lineno_width = if lineno_width == 0 {
59-
lineno_width
60-
} else if self.anonymized_line_numbers {
61-
Self::ANONYMIZED_LINE_NUM.len()
62-
} else {
63-
((lineno_width as f64).log10().floor() as usize) + 1
64-
};
65-
let inline_marks_width = self.body.iter().fold(0, |max, line| match line {
66-
DisplayLine::Source { inline_marks, .. } => cmp::max(inline_marks.len(), max),
67-
_ => max,
68-
});
69-
70-
for (i, line) in self.body.iter().enumerate() {
71-
self.format_line(line, lineno_width, inline_marks_width, f)?;
72-
if i + 1 < self.body.len() {
73-
f.write_char('\n')?;
74-
}
75-
}
76-
Ok(())
77-
}
78-
}
79-
80-
impl<'a> DisplayList<'a> {
81-
const ANONYMIZED_LINE_NUM: &'static str = "LL";
82-
const ERROR_TXT: &'static str = "error";
83-
const HELP_TXT: &'static str = "help";
84-
const INFO_TXT: &'static str = "info";
85-
const NOTE_TXT: &'static str = "note";
86-
const WARNING_TXT: &'static str = "warning";
87-
88-
#[inline]
89-
fn format_annotation_type(
90-
annotation_type: &DisplayAnnotationType,
91-
f: &mut fmt::Formatter<'_>,
92-
) -> fmt::Result {
93-
match annotation_type {
94-
DisplayAnnotationType::Error => f.write_str(Self::ERROR_TXT),
95-
DisplayAnnotationType::Help => f.write_str(Self::HELP_TXT),
96-
DisplayAnnotationType::Info => f.write_str(Self::INFO_TXT),
97-
DisplayAnnotationType::Note => f.write_str(Self::NOTE_TXT),
98-
DisplayAnnotationType::Warning => f.write_str(Self::WARNING_TXT),
99-
DisplayAnnotationType::None => Ok(()),
100-
}
101-
}
102-
103-
fn annotation_type_len(annotation_type: &DisplayAnnotationType) -> usize {
104-
match annotation_type {
105-
DisplayAnnotationType::Error => Self::ERROR_TXT.len(),
106-
DisplayAnnotationType::Help => Self::HELP_TXT.len(),
107-
DisplayAnnotationType::Info => Self::INFO_TXT.len(),
108-
DisplayAnnotationType::Note => Self::NOTE_TXT.len(),
109-
DisplayAnnotationType::Warning => Self::WARNING_TXT.len(),
110-
DisplayAnnotationType::None => 0,
111-
}
112-
}
113-
114-
fn get_annotation_style(&self, annotation_type: &DisplayAnnotationType) -> Box<dyn Style> {
115-
self.stylesheet.get_style(match annotation_type {
116-
DisplayAnnotationType::Error => StyleClass::Error,
117-
DisplayAnnotationType::Warning => StyleClass::Warning,
118-
DisplayAnnotationType::Info => StyleClass::Info,
119-
DisplayAnnotationType::Note => StyleClass::Note,
120-
DisplayAnnotationType::Help => StyleClass::Help,
121-
DisplayAnnotationType::None => StyleClass::None,
122-
})
123-
}
124-
125-
fn format_label(
126-
&self,
127-
label: &[DisplayTextFragment<'_>],
128-
f: &mut fmt::Formatter<'_>,
129-
) -> fmt::Result {
130-
let emphasis_style = self.stylesheet.get_style(StyleClass::Emphasis);
131-
132-
for fragment in label {
133-
match fragment.style {
134-
DisplayTextStyle::Regular => fragment.content.fmt(f)?,
135-
DisplayTextStyle::Emphasis => emphasis_style.paint(fragment.content, f)?,
136-
}
137-
}
138-
Ok(())
139-
}
140-
141-
fn format_annotation(
142-
&self,
143-
annotation: &Annotation<'_>,
144-
continuation: bool,
145-
in_source: bool,
146-
f: &mut fmt::Formatter<'_>,
147-
) -> fmt::Result {
148-
let color = self.get_annotation_style(&annotation.annotation_type);
149-
let formatted_len = if let Some(id) = &annotation.id {
150-
2 + id.len() + Self::annotation_type_len(&annotation.annotation_type)
151-
} else {
152-
Self::annotation_type_len(&annotation.annotation_type)
153-
};
154-
155-
if continuation {
156-
format_repeat_char(' ', formatted_len + 2, f)?;
157-
return self.format_label(&annotation.label, f);
158-
}
159-
if formatted_len == 0 {
160-
self.format_label(&annotation.label, f)
161-
} else {
162-
color.paint_fn(
163-
Box::new(|f| {
164-
Self::format_annotation_type(&annotation.annotation_type, f)?;
165-
if let Some(id) = &annotation.id {
166-
f.write_char('[')?;
167-
f.write_str(id)?;
168-
f.write_char(']')?;
169-
}
170-
Ok(())
171-
}),
172-
f,
173-
)?;
174-
if !is_annotation_empty(annotation) {
175-
if in_source {
176-
color.paint_fn(
177-
Box::new(|f| {
178-
f.write_str(": ")?;
179-
self.format_label(&annotation.label, f)
180-
}),
181-
f,
182-
)?;
183-
} else {
184-
f.write_str(": ")?;
185-
self.format_label(&annotation.label, f)?;
186-
}
187-
}
188-
Ok(())
189-
}
190-
}
191-
192-
#[inline]
193-
fn format_source_line(
194-
&self,
195-
line: &DisplaySourceLine<'_>,
196-
f: &mut fmt::Formatter<'_>,
197-
) -> fmt::Result {
198-
match line {
199-
DisplaySourceLine::Empty => Ok(()),
200-
DisplaySourceLine::Content { text, .. } => {
201-
f.write_char(' ')?;
202-
if let Some(margin) = self.margin {
203-
let line_len = text.chars().count();
204-
let mut left = margin.left(line_len);
205-
let right = margin.right(line_len);
206-
207-
if margin.was_cut_left() {
208-
// We have stripped some code/whitespace from the beginning, make it clear.
209-
"...".fmt(f)?;
210-
left += 3;
211-
}
212-
213-
// On long lines, we strip the source line, accounting for unicode.
214-
let mut taken = 0;
215-
let cut_right = if margin.was_cut_right(line_len) {
216-
taken += 3;
217-
true
218-
} else {
219-
false
220-
};
221-
// Specifies that it will end on the next character, so it will return
222-
// until the next one to the final condition.
223-
let mut ended = false;
224-
let range = text
225-
.char_indices()
226-
.skip(left)
227-
// Complete char iterator with final character
228-
.chain(once((text.len(), '\0')))
229-
// Take until the next one to the final condition
230-
.take_while(|(_, ch)| {
231-
// Fast return to iterate over final byte position
232-
if ended {
233-
return false;
234-
}
235-
// Make sure that the trimming on the right will fall within the terminal width.
236-
// FIXME: `unicode_width` sometimes disagrees with terminals on how wide a `char` is.
237-
// For now, just accept that sometimes the code line will be longer than desired.
238-
taken += unicode_width::UnicodeWidthChar::width(*ch).unwrap_or(1);
239-
if taken > right - left {
240-
ended = true;
241-
}
242-
true
243-
})
244-
// Reduce to start and end byte position
245-
.fold((None, 0), |acc, (i, _)| {
246-
if acc.0.is_some() {
247-
(acc.0, i)
248-
} else {
249-
(Some(i), i)
250-
}
251-
});
252-
253-
// Format text with margins
254-
text[range.0.expect("One character at line")..range.1].fmt(f)?;
255-
256-
if cut_right {
257-
// We have stripped some code after the right-most span end, make it clear we did so.
258-
"...".fmt(f)?;
259-
}
260-
Ok(())
261-
} else {
262-
text.fmt(f)
263-
}
264-
}
265-
DisplaySourceLine::Annotation {
266-
range,
267-
annotation,
268-
annotation_type,
269-
annotation_part,
270-
} => {
271-
let indent_char = match annotation_part {
272-
DisplayAnnotationPart::Standalone => ' ',
273-
DisplayAnnotationPart::LabelContinuation => ' ',
274-
DisplayAnnotationPart::Consequitive => ' ',
275-
DisplayAnnotationPart::MultilineStart => '_',
276-
DisplayAnnotationPart::MultilineEnd => '_',
277-
};
278-
let mark = match annotation_type {
279-
DisplayAnnotationType::Error => '^',
280-
DisplayAnnotationType::Warning => '-',
281-
DisplayAnnotationType::Info => '-',
282-
DisplayAnnotationType::Note => '-',
283-
DisplayAnnotationType::Help => '-',
284-
DisplayAnnotationType::None => ' ',
285-
};
286-
let color = self.get_annotation_style(annotation_type);
287-
let indent_length = match annotation_part {
288-
DisplayAnnotationPart::LabelContinuation => range.1,
289-
DisplayAnnotationPart::Consequitive => range.1,
290-
_ => range.0,
291-
};
292-
293-
color.paint_fn(
294-
Box::new(|f| {
295-
format_repeat_char(indent_char, indent_length + 1, f)?;
296-
format_repeat_char(mark, range.1 - indent_length, f)
297-
}),
298-
f,
299-
)?;
300-
301-
if !is_annotation_empty(annotation) {
302-
f.write_char(' ')?;
303-
color.paint_fn(
304-
Box::new(|f| {
305-
self.format_annotation(
306-
annotation,
307-
annotation_part == &DisplayAnnotationPart::LabelContinuation,
308-
true,
309-
f,
310-
)
311-
}),
312-
f,
313-
)?;
314-
}
315-
316-
Ok(())
317-
}
318-
}
319-
}
320-
321-
#[inline]
322-
fn format_raw_line(
323-
&self,
324-
line: &DisplayRawLine<'_>,
325-
lineno_width: usize,
326-
f: &mut fmt::Formatter<'_>,
327-
) -> fmt::Result {
328-
match line {
329-
DisplayRawLine::Origin {
330-
path,
331-
pos,
332-
header_type,
333-
} => {
334-
let header_sigil = match header_type {
335-
DisplayHeaderType::Initial => "-->",
336-
DisplayHeaderType::Continuation => ":::",
337-
};
338-
let lineno_color = self.stylesheet.get_style(StyleClass::LineNo);
339-
340-
if let Some((col, row)) = pos {
341-
format_repeat_char(' ', lineno_width, f)?;
342-
lineno_color.paint(header_sigil, f)?;
343-
f.write_char(' ')?;
344-
path.fmt(f)?;
345-
f.write_char(':')?;
346-
col.fmt(f)?;
347-
f.write_char(':')?;
348-
row.fmt(f)
349-
} else {
350-
format_repeat_char(' ', lineno_width, f)?;
351-
lineno_color.paint(header_sigil, f)?;
352-
f.write_char(' ')?;
353-
path.fmt(f)
354-
}
355-
}
356-
DisplayRawLine::Annotation {
357-
annotation,
358-
source_aligned,
359-
continuation,
360-
} => {
361-
if *source_aligned {
362-
if *continuation {
363-
format_repeat_char(' ', lineno_width + 3, f)?;
364-
} else {
365-
let lineno_color = self.stylesheet.get_style(StyleClass::LineNo);
366-
format_repeat_char(' ', lineno_width, f)?;
367-
f.write_char(' ')?;
368-
lineno_color.paint("=", f)?;
369-
f.write_char(' ')?;
370-
}
371-
}
372-
self.format_annotation(annotation, *continuation, false, f)
373-
}
374-
}
375-
}
376-
377-
#[inline]
378-
fn format_line(
379-
&self,
380-
dl: &DisplayLine<'_>,
381-
lineno_width: usize,
382-
inline_marks_width: usize,
383-
f: &mut fmt::Formatter<'_>,
384-
) -> fmt::Result {
385-
match dl {
386-
DisplayLine::Source {
387-
lineno,
388-
inline_marks,
389-
line,
390-
} => {
391-
let lineno_color = self.stylesheet.get_style(StyleClass::LineNo);
392-
if self.anonymized_line_numbers && lineno.is_some() {
393-
lineno_color.paint_fn(
394-
Box::new(|f| {
395-
f.write_str(Self::ANONYMIZED_LINE_NUM)?;
396-
f.write_str(" |")
397-
}),
398-
f,
399-
)?;
400-
} else {
401-
lineno_color.paint_fn(
402-
Box::new(|f| {
403-
match lineno {
404-
Some(n) => write!(f, "{:>width$}", n, width = lineno_width),
405-
None => format_repeat_char(' ', lineno_width, f),
406-
}?;
407-
f.write_str(" |")
408-
}),
409-
f,
410-
)?;
411-
}
412-
if *line != DisplaySourceLine::Empty {
413-
if !inline_marks.is_empty() || 0 < inline_marks_width {
414-
f.write_char(' ')?;
415-
self.format_inline_marks(inline_marks, inline_marks_width, f)?;
416-
}
417-
self.format_source_line(line, f)?;
418-
} else if !inline_marks.is_empty() {
419-
f.write_char(' ')?;
420-
self.format_inline_marks(inline_marks, inline_marks_width, f)?;
421-
}
422-
Ok(())
423-
}
424-
DisplayLine::Fold { inline_marks } => {
425-
f.write_str("...")?;
426-
if !inline_marks.is_empty() || 0 < inline_marks_width {
427-
format_repeat_char(' ', lineno_width, f)?;
428-
self.format_inline_marks(inline_marks, inline_marks_width, f)?;
429-
}
430-
Ok(())
431-
}
432-
DisplayLine::Raw(line) => self.format_raw_line(line, lineno_width, f),
433-
}
434-
}
435-
436-
fn format_inline_marks(
437-
&self,
438-
inline_marks: &[DisplayMark],
439-
inline_marks_width: usize,
440-
f: &mut fmt::Formatter<'_>,
441-
) -> fmt::Result {
442-
format_repeat_char(' ', inline_marks_width - inline_marks.len(), f)?;
443-
for mark in inline_marks {
444-
self.get_annotation_style(&mark.annotation_type).paint_fn(
445-
Box::new(|f| {
446-
f.write_char(match mark.mark_type {
447-
DisplayMarkType::AnnotationThrough => '|',
448-
DisplayMarkType::AnnotationStart => '/',
449-
})
450-
}),
451-
f,
452-
)?;
453-
}
454-
Ok(())
455-
}
456-
}

0 commit comments

Comments
 (0)
Please sign in to comment.