grit_pattern_matcher/pattern/
some.rs1use super::{
2 patterns::{Matcher, Pattern, PatternName},
3 resolved_pattern::ResolvedPattern,
4 State,
5};
6use crate::{constant::Constant, context::QueryContext};
7use grit_util::{error::GritResult, AnalysisLogs};
8
9#[derive(Debug, Clone)]
10pub struct Some<Q: QueryContext> {
11 pub pattern: Pattern<Q>,
12}
13
14impl<Q: QueryContext> Some<Q> {
15 pub fn new(pattern: Pattern<Q>) -> Self {
16 Self { pattern }
17 }
18}
19
20impl<Q: QueryContext> PatternName for Some<Q> {
21 fn name(&self) -> &'static str {
22 "SOME"
23 }
24}
25
26impl<Q: QueryContext> Matcher<Q> for Some<Q> {
27 fn execute<'a>(
28 &'a self,
29 binding: &Q::ResolvedPattern<'a>,
30 init_state: &mut State<'a, Q>,
31 context: &'a Q::ExecContext<'a>,
32 logs: &mut AnalysisLogs,
33 ) -> GritResult<bool> {
34 if let Some(items) = binding.get_list_binding_items() {
35 let mut did_match = false;
36 let mut cur_state = init_state.clone();
37 for item in items {
38 let state = cur_state.clone();
39 if self.pattern.execute(&item, &mut cur_state, context, logs)? {
40 did_match = true;
41 } else {
42 cur_state = state;
43 }
44 }
45 *init_state = cur_state;
46 Ok(did_match)
47 } else if let Some(items) = binding.get_list_items() {
48 let mut cur_state = init_state.clone();
49 let mut did_match = false;
50 for item in items {
51 let state = cur_state.clone();
52 if self.pattern.execute(item, &mut cur_state, context, logs)? {
53 did_match = true;
54 } else {
55 cur_state = state;
56 }
57 }
58 *init_state = cur_state;
59 Ok(did_match)
60 } else if let Some(map) = binding.get_map() {
61 let pattern = &self.pattern;
62 let mut cur_state = init_state.clone();
63 let mut did_match = false;
64 for (key, value) in map {
65 let state = cur_state.clone();
66 let key = ResolvedPattern::from_constant(Constant::String(key.clone()));
67 let resolved = ResolvedPattern::from_list_parts([key, value.clone()].into_iter());
68 if pattern.execute(&resolved, &mut cur_state, context, logs)? {
69 did_match = true;
70 } else {
71 cur_state = state;
72 }
73 }
74 *init_state = cur_state;
75 Ok(did_match)
76 } else {
77 Ok(false)
78 }
79 }
80}