sqruff_lib_core/parser/grammar/
conditional.rs1use 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}