sqruff_lib_core/parser/
matchable.rs1use std::ops::Deref;
2use std::sync::Arc;
3use std::sync::atomic::{AtomicU32, Ordering};
4
5use ahash::AHashSet;
6use enum_dispatch::enum_dispatch;
7
8use super::context::ParseContext;
9use super::grammar::anyof::AnyNumberOf;
10use super::grammar::conditional::Conditional;
11use super::grammar::delimited::Delimited;
12use super::grammar::noncode::NonCodeMatcher;
13use super::grammar::sequence::{Bracketed, Sequence};
14use super::grammar::{Anything, Nothing, Ref};
15use super::lookahead::LookaheadExclude;
16use super::match_result::MatchResult;
17use super::node_matcher::NodeMatcher;
18use super::parsers::{MultiStringParser, RegexParser, StringParser, TypedParser};
19use super::segments::ErasedSegment;
20use super::segments::bracketed::BracketedSegmentMatcher;
21use super::segments::meta::MetaSegment;
22use crate::dialects::Dialect;
23use crate::dialects::syntax::{SyntaxKind, SyntaxSet};
24use crate::errors::SQLParseError;
25
26#[derive(Clone, Debug, PartialEq)]
27pub struct Matchable {
28 inner: Arc<MatchableTraitImpl>,
29}
30
31impl Deref for Matchable {
32 type Target = MatchableTraitImpl;
33
34 fn deref(&self) -> &Self::Target {
35 &self.inner
36 }
37}
38
39impl Matchable {
40 pub fn new(matchable: MatchableTraitImpl) -> Self {
41 Self {
42 inner: Arc::new(matchable),
43 }
44 }
45
46 pub fn get_mut(&mut self) -> &mut MatchableTraitImpl {
47 Arc::get_mut(&mut self.inner).unwrap()
48 }
49
50 pub fn make_mut(&mut self) -> &mut MatchableTraitImpl {
51 Arc::make_mut(&mut self.inner)
52 }
53
54 pub fn as_conditional(&self) -> Option<&Conditional> {
55 match self.inner.as_ref() {
56 MatchableTraitImpl::Conditional(parser) => Some(parser),
57 _ => None,
58 }
59 }
60
61 pub fn as_indent(&self) -> Option<&MetaSegment> {
62 match self.inner.as_ref() {
63 MatchableTraitImpl::MetaSegment(parser) => Some(parser),
64 _ => None,
65 }
66 }
67
68 pub fn as_regex(&self) -> Option<&RegexParser> {
69 match self.inner.as_ref() {
70 MatchableTraitImpl::RegexParser(parser) => Some(parser),
71 _ => None,
72 }
73 }
74
75 pub fn as_ref(&self) -> Option<&Ref> {
76 match self.inner.as_ref() {
77 MatchableTraitImpl::Ref(parser) => Some(parser),
78 _ => None,
79 }
80 }
81
82 pub fn as_node_matcher(&mut self) -> Option<&mut NodeMatcher> {
83 match Arc::make_mut(&mut self.inner) {
84 MatchableTraitImpl::NodeMatcher(parser) => Some(parser),
85 _ => None,
86 }
87 }
88}
89
90#[enum_dispatch(MatchableTrait)]
91#[derive(Clone, Debug)]
92pub enum MatchableTraitImpl {
93 AnyNumberOf(AnyNumberOf),
94 Bracketed(Bracketed),
95 NodeMatcher(NodeMatcher),
96 NonCodeMatcher(NonCodeMatcher),
97 Nothing(Nothing),
98 Ref(Ref),
99 Sequence(Sequence),
100 StringParser(StringParser),
101 TypedParser(TypedParser),
102 MetaSegment(MetaSegment),
103 MultiStringParser(MultiStringParser),
104 RegexParser(RegexParser),
105 Delimited(Delimited),
106 Anything(Anything),
107 Conditional(Conditional),
108 BracketedSegmentMatcher(BracketedSegmentMatcher),
109 LookaheadExclude(LookaheadExclude),
110}
111
112impl PartialEq for MatchableTraitImpl {
113 fn eq(&self, other: &Self) -> bool {
114 match (self, other) {
115 (Self::Ref(a), Self::Ref(b)) => {
116 a.reference == b.reference
117 && a.optional == b.optional
118 && a.allow_gaps == b.allow_gaps
119 }
120 (Self::Delimited(a), Self::Delimited(b)) => {
121 a.base == b.base && a.allow_trailing == b.allow_trailing
122 }
123 (Self::StringParser(a), Self::StringParser(b)) => a == b,
124 (Self::TypedParser(a), Self::TypedParser(b)) => a == b,
125 (Self::MultiStringParser(a), Self::MultiStringParser(b)) => a == b,
126 _ => {
127 std::mem::discriminant(self) == std::mem::discriminant(other)
128 && self.is_optional() == other.is_optional()
129 && self.elements() == other.elements()
130 }
131 }
132 }
133}
134
135#[enum_dispatch]
136pub trait MatchableTrait {
137 fn get_type(&self) -> SyntaxKind {
138 todo!()
139 }
140
141 fn match_grammar(&self, _dialect: &Dialect) -> Option<Matchable> {
142 None
143 }
144
145 fn elements(&self) -> &[Matchable];
146
147 fn is_optional(&self) -> bool {
149 false
150 }
151
152 fn simple(
159 &self,
160 parse_context: &ParseContext,
161 crumbs: Option<Vec<&str>>,
162 ) -> Option<(AHashSet<String>, SyntaxSet)> {
163 let match_grammar = self.match_grammar(parse_context.dialect())?;
164
165 match_grammar.simple(parse_context, crumbs)
166 }
167
168 fn match_segments(
169 &self,
170 _segments: &[ErasedSegment],
171 _idx: u32,
172 _parse_context: &mut ParseContext,
173 ) -> Result<MatchResult, SQLParseError> {
174 todo!();
175 }
176
177 fn cache_key(&self) -> MatchableCacheKey {
178 unimplemented!("{}", std::any::type_name::<Self>())
179 }
180
181 #[track_caller]
182 fn copy(
183 &self,
184 _insert: Option<Vec<Matchable>>,
185 _at: Option<usize>,
186 _before: Option<Matchable>,
187 _remove: Option<Vec<Matchable>>,
188 _terminators: Vec<Matchable>,
189 _replace_terminators: bool,
190 ) -> Matchable {
191 unimplemented!("{}", std::any::type_name::<Self>())
192 }
193}
194
195pub type MatchableCacheKey = u32;
196
197pub fn next_matchable_cache_key() -> MatchableCacheKey {
198 static ID: AtomicU32 = AtomicU32::new(1);
202
203 ID.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |id| id.checked_add(1))
204 .unwrap()
205}