grit_pattern_matcher/pattern/
some.rs

1use 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}