grit_pattern_matcher/pattern/
map.rs1use super::{
2 patterns::{Matcher, Pattern, PatternName},
3 resolved_pattern::ResolvedPattern,
4 state::State,
5};
6use crate::context::QueryContext;
7use grit_util::{error::GritResult, AnalysisLogs};
8use std::collections::BTreeMap;
9
10#[derive(Debug, Clone)]
11pub struct GritMap<Q: QueryContext> {
12 pub elements: BTreeMap<String, Pattern<Q>>,
13}
14
15impl<Q: QueryContext> GritMap<Q> {
16 pub fn new(elements: BTreeMap<String, Pattern<Q>>) -> Self {
17 Self { elements }
18 }
19
20 pub fn get(&self, key: &str) -> Option<&Pattern<Q>> {
21 self.elements.get(key)
22 }
23}
24
25impl<Q: QueryContext> PatternName for GritMap<Q> {
26 fn name(&self) -> &'static str {
27 "MAP"
28 }
29}
30
31impl<Q: QueryContext> Matcher<Q> for GritMap<Q> {
32 fn execute<'a>(
33 &'a self,
34 binding: &Q::ResolvedPattern<'a>,
35 state: &mut State<'a, Q>,
36 context: &'a Q::ExecContext<'a>,
37 logs: &mut AnalysisLogs,
38 ) -> GritResult<bool> {
39 let Some(map) = binding.get_map() else {
40 return Ok(false);
41 };
42
43 for element in map.iter() {
44 if let Some(pattern) = self.elements.get(element.0) {
45 if !pattern.execute(element.1, state, context, logs)? {
46 return Ok(false);
47 }
48 } else {
49 return Ok(false);
50 }
51 }
52 for element in self.elements.iter() {
53 if !map.contains_key(element.0) {
54 return Ok(false);
55 }
56 }
57 Ok(true)
58 }
59}