sqruff_lib_core/
errors.rs1use std::fmt::Display;
2use std::ops::{Deref, DerefMut, Range};
3
4use fancy_regex::Regex;
5
6use super::parser::segments::ErasedSegment;
7use crate::helpers::Config;
8use crate::parser::markers::PositionMarker;
9
10#[derive(Debug, PartialEq, Clone, Default)]
11pub struct SQLBaseError {
12 pub fixable: bool,
13 pub line_no: usize,
14 pub line_pos: usize,
15 pub description: String,
16 pub rule: Option<ErrorStructRule>,
17 pub source_slice: Range<usize>,
18}
19
20#[derive(Debug, PartialEq, Clone, Default)]
21pub struct ErrorStructRule {
22 pub name: &'static str,
23 pub code: &'static str,
24}
25
26impl SQLBaseError {
27 pub fn rule_code(&self) -> &'static str {
28 self.rule.as_ref().map_or("????", |rule| rule.code)
29 }
30
31 pub fn set_position_marker(&mut self, position_marker: PositionMarker) {
32 let (line_no, line_pos) = position_marker.source_position();
33
34 self.line_no = line_no;
35 self.line_pos = line_pos;
36
37 self.source_slice = position_marker.source_slice.clone();
38 }
39
40 pub fn desc(&self) -> &str {
41 &self.description
42 }
43}
44
45impl Display for SQLBaseError {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 write!(f, "{}", self.description)
48 }
49}
50
51#[derive(Debug, Clone)]
52pub struct SQLLintError {
53 base: SQLBaseError,
54}
55
56impl SQLLintError {
57 pub fn new(description: &str, segment: ErasedSegment, fixable: bool) -> Self {
58 Self {
59 base: SQLBaseError::default().config(|this| {
60 this.description = description.into();
61 this.set_position_marker(segment.get_position_marker().unwrap().clone());
62 this.fixable = fixable;
63 }),
64 }
65 }
66}
67
68impl Deref for SQLLintError {
69 type Target = SQLBaseError;
70
71 fn deref(&self) -> &Self::Target {
72 &self.base
73 }
74}
75
76impl DerefMut for SQLLintError {
77 fn deref_mut(&mut self) -> &mut Self::Target {
78 &mut self.base
79 }
80}
81
82impl From<SQLLintError> for SQLBaseError {
83 fn from(value: SQLLintError) -> Self {
84 value.base
85 }
86}
87
88impl From<SQLBaseError> for SQLLintError {
89 fn from(value: SQLBaseError) -> Self {
90 Self { base: value }
91 }
92}
93
94#[derive(Debug, PartialEq, Clone)]
95pub struct SQLTemplaterError {}
96
97impl Display for SQLTemplaterError {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 write!(f, "SQLTemplaterError")
100 }
101}
102
103#[derive(Debug)]
105pub struct SQLFluffUserError {
106 pub value: String,
107}
108
109impl SQLFluffUserError {
110 pub fn new(value: String) -> SQLFluffUserError {
111 SQLFluffUserError { value }
112 }
113}
114
115impl Display for SQLFluffUserError {
116 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117 f.write_str(&self.value)
118 }
119}
120
121#[derive(Debug)]
122pub struct SQLParseError {
123 pub description: String,
124 pub segment: Option<ErasedSegment>,
125}
126
127impl SQLParseError {
128 pub fn matches(&self, regexp: &str) -> bool {
129 let value = &self.description;
130 let regex = Regex::new(regexp).expect("Invalid regex pattern");
131
132 if let Ok(true) = regex.is_match(value) {
133 true
134 } else {
135 let msg = format!("Regex pattern did not match.\nRegex: {regexp:?}\nInput: {value:?}");
136
137 if regexp == value {
138 panic!("{msg}\nDid you mean to escape the regex?");
139 } else {
140 panic!("{}", msg);
141 }
142 }
143 }
144}
145
146impl From<SQLParseError> for SQLBaseError {
147 fn from(value: SQLParseError) -> Self {
148 let (mut line_no, mut line_pos) = Default::default();
149
150 let pos_marker = value
151 .segment
152 .as_ref()
153 .and_then(|segment| segment.get_position_marker());
154
155 if let Some(pos_marker) = pos_marker {
156 (line_no, line_pos) = pos_marker.source_position();
157 }
158
159 Self::default().config(|this| {
160 this.line_no = line_no;
161 this.line_pos = line_pos;
162 this.description = value.description;
163 })
164 }
165}
166
167#[derive(PartialEq, Eq, Debug)]
168pub struct SQLLexError {
169 message: String,
170 position_marker: PositionMarker,
171}
172
173impl SQLLexError {
174 pub fn new(message: String, position_marker: PositionMarker) -> SQLLexError {
175 SQLLexError {
176 message,
177 position_marker,
178 }
179 }
180}
181
182#[derive(Debug)]
183pub struct SQLFluffSkipFile {
184 #[allow(dead_code)]
185 value: String,
186}
187
188impl SQLFluffSkipFile {
189 pub fn new(value: String) -> SQLFluffSkipFile {
190 SQLFluffSkipFile { value }
191 }
192}