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.
23 pub fn enable_colors(self, enable_colors
: bool
) -> Self {
30 /// Creates a new [`FormatReportFormatter`] from the settings in this builder.
31 pub fn build(self) -> FormatReportFormatter
<'a
> {
32 FormatReportFormatter
{
34 enable_colors
: self.enable_colors
,
39 /// Formats the warnings/errors in a [`FormatReport`].
41 /// Can be created using a [`FormatReportFormatterBuilder`].
42 pub struct FormatReportFormatter
<'a
> {
43 report
: &'a FormatReport
,
47 impl<'a
> Display
for FormatReportFormatter
<'a
> {
48 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
49 let errors_by_file
= &self.report
.internal
.borrow().0;
51 let opt
= FormatOptions
{
52 color
: self.enable_colors
,
56 for (file
, errors
) in errors_by_file
{
58 let error_kind
= error
.kind
.to_string();
59 let title
= Some(Annotation
{
60 id
: if error
.is_internal() {
65 label
: Some(&error_kind
),
66 annotation_type
: error_kind_to_snippet_annotation_type(&error
.kind
),
69 let message_suffix
= error
.msg_suffix();
70 let footer
= if !message_suffix
.is_empty() {
73 label
: Some(message_suffix
),
74 annotation_type
: AnnotationType
::Note
,
80 let origin
= format
!("{}:{}", file
, error
.line
);
82 source
: &error
.line_buffer
.clone(),
83 line_start
: error
.line
,
84 origin
: Some(origin
.as_str()),
86 annotations
: slice_annotation(error
).into_iter().collect(),
89 let snippet
= Snippet
{
91 footer
: footer
.into_iter().collect(),
95 writeln
!(f
, "{}\n", DisplayList
::from(snippet
))?
;
99 if !errors_by_file
.is_empty() {
101 "rustfmt has failed to format. See previous {} errors.",
102 self.report
.warning_count()
104 let snippet
= Snippet
{
105 title
: Some(Annotation
{
108 annotation_type
: AnnotationType
::Warning
,
114 writeln
!(f
, "{}", DisplayList
::from(snippet
))?
;
121 fn slice_annotation(error
: &FormattingError
) -> Option
<SourceAnnotation
<'_
>> {
122 let (range_start
, range_length
) = error
.format_len();
123 let range_end
= range_start
+ range_length
;
125 if range_length
> 0 {
126 Some(SourceAnnotation
{
127 annotation_type
: AnnotationType
::Error
,
128 range
: (range_start
, range_end
),
136 fn error_kind_to_snippet_annotation_type(error_kind
: &ErrorKind
) -> AnnotationType
{
138 ErrorKind
::LineOverflow(..)
139 | ErrorKind
::TrailingWhitespace
140 | ErrorKind
::IoError(_
)
141 | ErrorKind
::ModuleResolutionError(_
)
142 | ErrorKind
::ParseError
143 | ErrorKind
::LostComment
144 | ErrorKind
::LicenseCheck
146 | ErrorKind
::InvalidGlobPattern(_
)
147 | ErrorKind
::VersionMismatch
=> AnnotationType
::Error
,
148 ErrorKind
::BadIssue(_
) | ErrorKind
::DeprecatedAttr
=> AnnotationType
::Warning
,