grit_pattern_matcher/pattern/
dynamic_snippet.rs1use super::{
2 accessor::Accessor,
3 call_built_in::CallBuiltIn,
4 functions::{CallForeignFunction, CallFunction},
5 list_index::ListIndex,
6 patterns::{Matcher, PatternName},
7 resolved_pattern::ResolvedPattern,
8 variable::Variable,
9 State,
10};
11use crate::context::{ExecContext, QueryContext};
12use grit_util::{error::GritResult, AnalysisLogs};
13
14#[derive(Debug, Clone)]
15pub enum DynamicSnippetPart {
16 String(String),
17 Variable(Variable),
18}
19
20#[derive(Debug, Clone)]
21pub struct DynamicSnippet {
22 pub parts: Vec<DynamicSnippetPart>,
23}
24
25#[derive(Debug, Clone)]
26pub struct DynamicList<Q: QueryContext> {
27 pub elements: Vec<DynamicPattern<Q>>,
28}
29
30#[derive(Debug, Clone)]
31pub enum DynamicPattern<Q: QueryContext> {
32 Variable(Variable),
33 Accessor(Box<Accessor<Q>>),
34 ListIndex(Box<ListIndex<Q>>),
35 Snippet(DynamicSnippet),
36 List(DynamicList<Q>),
37 CallBuiltIn(CallBuiltIn<Q>),
38 CallFunction(CallFunction<Q>),
39 CallForeignFunction(CallForeignFunction<Q>),
40}
41
42impl<Q: QueryContext> DynamicPattern<Q> {
43 pub fn text<'a>(
44 &'a self,
45 state: &mut State<'a, Q>,
46 context: &'a Q::ExecContext<'a>,
47 logs: &mut AnalysisLogs,
48 ) -> GritResult<String> {
49 let resolved = Q::ResolvedPattern::from_dynamic_pattern(self, state, context, logs)?;
50 Ok(resolved.text(&state.files, context.language())?.to_string())
51 }
52
53 pub fn from_str_constant(s: &str) -> GritResult<Self> {
55 let parts = vec![DynamicSnippetPart::String(s.to_string())];
56 Ok(DynamicPattern::Snippet(DynamicSnippet { parts }))
57 }
58}
59
60impl<Q: QueryContext> PatternName for DynamicPattern<Q> {
61 fn name(&self) -> &'static str {
62 "DYNAMIC_PATTERN"
63 }
64}
65
66impl<Q: QueryContext> Matcher<Q> for DynamicPattern<Q> {
67 fn execute<'a>(
68 &'a self,
69 binding: &Q::ResolvedPattern<'a>,
70 state: &mut State<'a, Q>,
71 context: &'a Q::ExecContext<'a>,
72 logs: &mut AnalysisLogs,
73 ) -> GritResult<bool> {
74 if binding.text(&state.files, context.language())? == self.text(state, context, logs)? {
75 Ok(true)
76 } else {
77 Ok(false)
78 }
79 }
80}
81
82impl PatternName for DynamicSnippet {
83 fn name(&self) -> &'static str {
84 "DYNAMIC_SNIPPET"
85 }
86}