grit_pattern_matcher/pattern/
any.rs

1use super::{
2    functions::{Evaluator, FuncEvaluation},
3    patterns::{Matcher, Pattern, PatternName},
4    predicates::Predicate,
5    State,
6};
7use crate::context::QueryContext;
8use core::fmt::Debug;
9use grit_util::{error::GritResult, AnalysisLogs};
10
11#[derive(Debug, Clone)]
12pub struct Any<Q: QueryContext> {
13    pub patterns: Vec<Pattern<Q>>,
14}
15
16impl<Q: QueryContext> Any<Q> {
17    pub fn new(patterns: Vec<Pattern<Q>>) -> Self {
18        Self { patterns }
19    }
20}
21
22impl<Q: QueryContext> PatternName for Any<Q> {
23    fn name(&self) -> &'static str {
24        "ANY"
25    }
26}
27
28impl<Q: QueryContext> Matcher<Q> for Any<Q> {
29    // apply all successful updates to the state
30    // must have at least one successful match
31    // return soft and failed on failure
32    fn execute<'a>(
33        &'a self,
34        binding: &Q::ResolvedPattern<'a>,
35        init_state: &mut State<'a, Q>,
36        context: &'a Q::ExecContext<'a>,
37        logs: &mut AnalysisLogs,
38    ) -> GritResult<bool> {
39        let mut matched = false;
40        let mut cur_state = init_state.clone();
41        for pattern in &self.patterns {
42            let state = cur_state.clone();
43            if pattern.execute(binding, &mut cur_state, context, logs)? {
44                matched = true;
45            } else {
46                cur_state = state;
47            }
48        }
49        if matched {
50            *init_state = cur_state;
51            Ok(true)
52        } else {
53            Ok(false)
54        }
55    }
56}
57#[derive(Debug, Clone)]
58pub struct PrAny<Q: QueryContext> {
59    pub predicates: Vec<Predicate<Q>>,
60}
61
62impl<Q: QueryContext> PrAny<Q> {
63    pub fn new(predicates: Vec<Predicate<Q>>) -> Self {
64        Self { predicates }
65    }
66}
67
68impl<Q: QueryContext> PatternName for PrAny<Q> {
69    fn name(&self) -> &'static str {
70        "PREDICATE_ANY"
71    }
72}
73
74impl<Q: QueryContext> Evaluator<Q> for PrAny<Q> {
75    fn execute_func<'a>(
76        &'a self,
77        init_state: &mut State<'a, Q>,
78        context: &'a Q::ExecContext<'a>,
79        logs: &mut AnalysisLogs,
80    ) -> GritResult<FuncEvaluation<Q>> {
81        let mut matched = false;
82        let mut cur_state = init_state.clone();
83        for predicate in &self.predicates {
84            let state = cur_state.clone();
85            if predicate
86                .execute_func(&mut cur_state, context, logs)?
87                .predicator
88            {
89                matched = true;
90            } else {
91                cur_state = state;
92            }
93        }
94        if matched {
95            *init_state = cur_state;
96            Ok(FuncEvaluation {
97                predicator: true,
98                ret_val: None,
99            })
100        } else {
101            Ok(FuncEvaluation {
102                predicator: false,
103                ret_val: None,
104            })
105        }
106    }
107}