sqruff_lib_core/
errors.rsuse std::ops::{Deref, DerefMut, Range};
use fancy_regex::Regex;
use super::parser::segments::base::ErasedSegment;
use crate::helpers::Config;
use crate::parser::markers::PositionMarker;
type CheckTuple = (&'static str, usize, usize);
pub trait SqlError {
fn fixable(&self) -> bool;
fn rule_code(&self) -> Option<&'static str>;
fn identifier(&self) -> &'static str;
fn check_tuple(&self) -> CheckTuple;
}
#[derive(Debug, PartialEq, Clone)]
pub struct SQLBaseError {
pub fatal: bool,
pub ignore: bool,
pub warning: bool,
pub line_no: usize,
pub line_pos: usize,
pub description: String,
pub rule: Option<ErrorStructRule>,
pub source_slice: Range<usize>,
}
#[derive(Debug, PartialEq, Clone, Default)]
pub struct ErrorStructRule {
pub name: &'static str,
pub code: &'static str,
}
impl Default for SQLBaseError {
fn default() -> Self {
Self::new()
}
}
impl SQLBaseError {
pub fn new() -> Self {
Self {
description: String::new(),
fatal: false,
ignore: false,
warning: false,
line_no: 0,
line_pos: 0,
rule: None,
source_slice: 0..0,
}
}
pub fn rule_code(&self) -> &'static str {
self.rule.as_ref().map_or("????", |rule| rule.code)
}
pub fn set_position_marker(&mut self, position_marker: PositionMarker) {
let (line_no, line_pos) = position_marker.source_position();
self.line_no = line_no;
self.line_pos = line_pos;
self.source_slice = position_marker.source_slice;
}
pub fn desc(&self) -> &str {
&self.description
}
}
impl SqlError for SQLBaseError {
fn fixable(&self) -> bool {
false
}
fn rule_code(&self) -> Option<&'static str> {
None
}
fn identifier(&self) -> &'static str {
"base"
}
fn check_tuple(&self) -> CheckTuple {
("", self.line_no, self.line_pos)
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct SQLLintError {
base: SQLBaseError,
}
impl SQLLintError {
pub fn new(description: &str, segment: ErasedSegment) -> Self {
Self {
base: SQLBaseError::new().config(|this| {
this.description = description.into();
this.set_position_marker(segment.get_position_marker().unwrap().clone());
}),
}
}
}
impl Deref for SQLLintError {
type Target = SQLBaseError;
fn deref(&self) -> &Self::Target {
&self.base
}
}
impl DerefMut for SQLLintError {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.base
}
}
impl From<SQLLintError> for SQLBaseError {
fn from(value: SQLLintError) -> Self {
value.base
}
}
impl From<SQLBaseError> for SQLLintError {
fn from(value: SQLBaseError) -> Self {
Self { base: value }
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct SQLTemplaterError {}
impl SqlError for SQLTemplaterError {
fn fixable(&self) -> bool {
false
}
fn rule_code(&self) -> Option<&'static str> {
None
}
fn identifier(&self) -> &'static str {
"templater"
}
fn check_tuple(&self) -> CheckTuple {
("", 0, 0)
}
}
#[derive(Debug)]
pub struct SQLFluffUserError {
#[allow(dead_code)]
pub value: String,
}
impl SQLFluffUserError {
pub fn new(value: String) -> SQLFluffUserError {
SQLFluffUserError { value }
}
}
#[derive(Debug)]
pub struct ValueError {
#[allow(dead_code)]
value: String,
}
impl ValueError {
pub fn new(value: String) -> ValueError {
ValueError { value }
}
}
#[derive(Debug)]
pub struct SQLParseError {
pub description: String,
pub segment: Option<ErasedSegment>,
}
impl SQLParseError {
pub fn matches(&self, regexp: &str) -> bool {
let value = &self.description;
let regex = Regex::new(regexp).expect("Invalid regex pattern");
if let Ok(true) = regex.is_match(value) {
true
} else {
let msg = format!(
"Regex pattern did not match.\nRegex: {:?}\nInput: {:?}",
regexp, value
);
if regexp == value {
panic!("{}\nDid you mean to escape the regex?", msg);
} else {
panic!("{}", msg);
}
}
}
}
impl From<SQLParseError> for SQLBaseError {
fn from(value: SQLParseError) -> Self {
let (mut line_no, mut line_pos) = Default::default();
let pos_marker = value
.segment
.as_ref()
.and_then(|segment| segment.get_position_marker());
if let Some(pos_marker) = pos_marker {
(line_no, line_pos) = pos_marker.source_position();
}
Self::new().config(|this| {
this.fatal = true;
this.line_no = line_no;
this.line_pos = line_pos;
})
}
}
#[derive(PartialEq, Eq, Debug)]
pub struct SQLLexError {
message: String,
position_marker: PositionMarker,
}
impl SQLLexError {
pub fn new(message: String, position_marker: PositionMarker) -> SQLLexError {
SQLLexError {
message,
position_marker,
}
}
}
#[derive(Debug)]
pub struct SQLFluffSkipFile {
#[allow(dead_code)]
value: String,
}
impl SQLFluffSkipFile {
pub fn new(value: String) -> SQLFluffSkipFile {
SQLFluffSkipFile { value }
}
}