1 use crate::formatting
::FormattingError
;
2 use crate::{ErrorKind, FormatReport}
;
3 use annotate_snippets
::display_list
::{DisplayList, FormatOptions}
;
4 use annotate_snippets
::snippet
::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation}
;
5 use std
::fmt
::{self, Display}
;
7 /// A builder for [`FormatReportFormatter`].
8 pub struct FormatReportFormatterBuilder
<'a
> {
9 report
: &'a FormatReport
,
13 impl<'a
> FormatReportFormatterBuilder
<'a
> {
14 /// Creates a new [`FormatReportFormatterBuilder`].
15 pub fn new(report
: &'a FormatReport
) -> Self {
22 /// Enables colors and formatting in the output.
24 pub fn enable_colors(self, enable_colors
: bool
) -> Self {
31 /// Creates a new [`FormatReportFormatter`] from the settings in this builder.
32 pub fn build(self) -> FormatReportFormatter
<'a
> {
33 FormatReportFormatter
{
35 enable_colors
: self.enable_colors
,
40 /// Formats the warnings/errors in a [`FormatReport`].
42 /// Can be created using a [`FormatReportFormatterBuilder`].
43 pub struct FormatReportFormatter
<'a
> {
44 report
: &'a FormatReport
,
48 impl<'a
> Display
for FormatReportFormatter
<'a
> {
49 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
50 let errors_by_file
= &self.report
.internal
.borrow().0;
52 let opt
= FormatOptions
{
53 color
: self.enable_colors
,
57 for (file
, errors
) in errors_by_file
{
59 let error_kind
= error
.kind
.to_string();
60 let title
= Some(Annotation
{
61 id
: if error
.is_internal() {
66 label
: Some(&error_kind
),
67 annotation_type
: error_kind_to_snippet_annotation_type(&error
.kind
),
70 let message_suffix
= error
.msg_suffix();
71 let footer
= if !message_suffix
.is_empty() {
74 label
: Some(message_suffix
),
75 annotation_type
: AnnotationType
::Note
,
81 let origin
= format
!("{}:{}", file
, error
.line
);
83 source
: &error
.line_buffer
.clone(),
84 line_start
: error
.line
,
85 origin
: Some(origin
.as_str()),
87 annotations
: slice_annotation(error
).into_iter().collect(),
90 let snippet
= Snippet
{
92 footer
: footer
.into_iter().collect(),
96 writeln
!(f
, "{}\n", DisplayList
::from(snippet
))?
;
100 if !errors_by_file
.is_empty() {
102 "rustfmt has failed to format. See previous {} errors.",
103 self.report
.warning_count()
105 let snippet
= Snippet
{
106 title
: Some(Annotation
{
109 annotation_type
: AnnotationType
::Warning
,
115 writeln
!(f
, "{}", DisplayList
::from(snippet
))?
;
122 fn slice_annotation(error
: &FormattingError
) -> Option
<SourceAnnotation
<'_
>> {
123 let (range_start
, range_length
) = error
.format_len();
124 let range_end
= range_start
+ range_length
;
126 if range_length
> 0 {
127 Some(SourceAnnotation
{
128 annotation_type
: AnnotationType
::Error
,
129 range
: (range_start
, range_end
),
137 fn error_kind_to_snippet_annotation_type(error_kind
: &ErrorKind
) -> AnnotationType
{
139 ErrorKind
::LineOverflow(..)
140 | ErrorKind
::TrailingWhitespace
141 | ErrorKind
::IoError(_
)
142 | ErrorKind
::ModuleResolutionError(_
)
143 | ErrorKind
::ParseError
144 | ErrorKind
::LostComment
146 | ErrorKind
::InvalidGlobPattern(_
)
147 | ErrorKind
::VersionMismatch
=> AnnotationType
::Error
,
148 ErrorKind
::DeprecatedAttr
=> AnnotationType
::Warning
,