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