sqruff_lib_core/parser/grammar/
conditional.rs

1use crate::errors::SQLParseError;
2use crate::parser::context::ParseContext;
3use crate::parser::match_result::{MatchResult, Span};
4use crate::parser::matchable::{Matchable, MatchableTrait};
5use crate::parser::segments::ErasedSegment;
6use crate::parser::segments::meta::Indent;
7
8#[derive(Clone, Debug, PartialEq)]
9pub struct Conditional {
10    meta: Indent,
11    indented_joins: bool,
12    indented_using_on: bool,
13    indented_on_contents: bool,
14    indented_then: bool,
15    indented_then_contents: bool,
16    indented_joins_on: bool,
17    indented_ctes: bool,
18}
19
20impl Conditional {
21    pub fn new(meta: Indent) -> Self {
22        Self {
23            meta,
24            indented_joins: false,
25            indented_using_on: false,
26            indented_on_contents: false,
27            indented_then: false,
28            indented_then_contents: false,
29            indented_joins_on: false,
30            indented_ctes: false,
31        }
32    }
33
34    pub fn indented_ctes(mut self) -> Self {
35        self.indented_ctes = true;
36        self
37    }
38
39    pub fn indented_joins(mut self) -> Self {
40        self.indented_joins = true;
41        self
42    }
43
44    pub fn indented_using_on(mut self) -> Self {
45        self.indented_using_on = true;
46        self
47    }
48
49    pub fn indented_on_contents(mut self) -> Self {
50        self.indented_on_contents = true;
51        self
52    }
53
54    pub fn indented_then(mut self) -> Self {
55        self.indented_then = true;
56        self
57    }
58
59    pub fn indented_then_contents(mut self) -> Self {
60        self.indented_then_contents = true;
61        self
62    }
63
64    pub fn indented_joins_on(mut self) -> Self {
65        self.indented_joins_on = true;
66        self
67    }
68
69    fn is_enabled(&self, parse_context: &mut ParseContext) -> bool {
70        macro_rules! check_config_match {
71            ($self:expr, $parse_context:expr, $field:ident) => {{
72                let config_value = $parse_context
73                    .indentation_config
74                    .get(stringify!($field))
75                    .copied()
76                    .unwrap_or_default();
77
78                if $self.$field && $self.$field != config_value {
79                    return false;
80                }
81            }};
82        }
83
84        check_config_match!(self, parse_context, indented_joins);
85        check_config_match!(self, parse_context, indented_using_on);
86        check_config_match!(self, parse_context, indented_on_contents);
87        check_config_match!(self, parse_context, indented_then);
88        check_config_match!(self, parse_context, indented_then_contents);
89        check_config_match!(self, parse_context, indented_joins_on);
90        check_config_match!(self, parse_context, indented_ctes);
91
92        true
93    }
94}
95
96impl MatchableTrait for Conditional {
97    fn elements(&self) -> &[Matchable] {
98        &[]
99    }
100
101    fn match_segments(
102        &self,
103        _segments: &[ErasedSegment],
104        idx: u32,
105        parse_context: &mut ParseContext,
106    ) -> Result<MatchResult, SQLParseError> {
107        if !self.is_enabled(parse_context) {
108            return Ok(MatchResult::empty_at(idx));
109        }
110
111        Ok(MatchResult {
112            span: Span {
113                start: idx,
114                end: idx,
115            },
116            insert_segments: vec![(idx, self.meta.kind)],
117            ..Default::default()
118        })
119    }
120}