ruff_formatter/
diagnostics.rs1use crate::GroupId;
2use crate::prelude::TagKind;
3use ruff_text_size::TextRange;
4use std::error::Error;
5
6#[derive(Debug, PartialEq, Eq, Copy, Clone)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub enum FormatError {
10 SyntaxError { message: &'static str },
13 RangeError { input: TextRange, tree: TextRange },
16
17 InvalidDocument(InvalidDocumentError),
19
20 PoorLayout,
27}
28
29impl std::fmt::Display for FormatError {
30 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 match self {
32 FormatError::SyntaxError { message } => {
33 std::write!(fmt, "syntax error: {message}")
34 }
35 FormatError::RangeError { input, tree } => std::write!(
36 fmt,
37 "formatting range {input:?} is larger than syntax tree {tree:?}"
38 ),
39 FormatError::InvalidDocument(error) => std::write!(
40 fmt,
41 "Invalid document: {error}\n\n This is an internal Ruff error. Please report if necessary."
42 ),
43 FormatError::PoorLayout => {
44 std::write!(
45 fmt,
46 "Poor layout: The formatter wasn't able to pick a good layout for your document. This is an internal Ruff error. Please report if necessary."
47 )
48 }
49 }
50 }
51}
52
53impl Error for FormatError {}
54
55impl From<PrintError> for FormatError {
56 fn from(error: PrintError) -> Self {
57 FormatError::from(&error)
58 }
59}
60
61impl From<&PrintError> for FormatError {
62 fn from(error: &PrintError) -> Self {
63 match error {
64 PrintError::InvalidDocument(reason) => FormatError::InvalidDocument(*reason),
65 }
66 }
67}
68
69impl FormatError {
70 pub fn syntax_error(message: &'static str) -> Self {
71 Self::SyntaxError { message }
72 }
73}
74
75#[derive(Debug, Copy, Clone, Eq, PartialEq)]
76#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
77pub enum InvalidDocumentError {
78 StartEndTagMismatch {
86 start_kind: TagKind,
87 end_kind: TagKind,
88 },
89
90 StartTagMissing {
97 kind: TagKind,
98 },
99
100 ExpectedStart {
105 expected_start: TagKind,
106 actual: ActualStart,
107 },
108
109 UnknownGroupId {
110 group_id: GroupId,
111 },
112}
113
114#[derive(Debug, Copy, Clone, Eq, PartialEq)]
115#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
116pub enum ActualStart {
117 Content,
119
120 Start(TagKind),
122
123 End(TagKind),
125
126 EndOfDocument,
128}
129
130impl std::fmt::Display for InvalidDocumentError {
131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132 match self {
133 InvalidDocumentError::StartEndTagMismatch {
134 start_kind,
135 end_kind,
136 } => {
137 std::write!(
138 f,
139 "Expected end tag of kind {start_kind:?} but found {end_kind:?}."
140 )
141 }
142 InvalidDocumentError::StartTagMissing { kind } => {
143 std::write!(f, "End tag of kind {kind:?} without matching start tag.")
144 }
145 InvalidDocumentError::ExpectedStart {
146 expected_start,
147 actual,
148 } => match actual {
149 ActualStart::EndOfDocument => {
150 std::write!(
151 f,
152 "Expected start tag of kind {expected_start:?} but at the end of document."
153 )
154 }
155 ActualStart::Start(start) => {
156 std::write!(
157 f,
158 "Expected start tag of kind {expected_start:?} but found start tag of kind {start:?}."
159 )
160 }
161 ActualStart::End(end) => {
162 std::write!(
163 f,
164 "Expected start tag of kind {expected_start:?} but found end tag of kind {end:?}."
165 )
166 }
167 ActualStart::Content => {
168 std::write!(
169 f,
170 "Expected start tag of kind {expected_start:?} but found non-tag element."
171 )
172 }
173 },
174 InvalidDocumentError::UnknownGroupId { group_id } => {
175 std::write!(
176 f,
177 "Encountered unknown group id {group_id:?}. Ensure that the group with the id {group_id:?} exists and that the group is a parent of or comes before the element referring to it."
178 )
179 }
180 }
181 }
182}
183
184#[derive(Debug, Clone, Eq, PartialEq)]
185pub enum PrintError {
186 InvalidDocument(InvalidDocumentError),
187}
188
189impl Error for PrintError {}
190
191impl std::fmt::Display for PrintError {
192 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
193 match self {
194 PrintError::InvalidDocument(inner) => {
195 std::write!(f, "Invalid document: {inner}")
196 }
197 }
198 }
199}