1mod kind;
9mod node_match;
10mod pattern;
11mod text;
12
13use crate::Doc;
14use crate::{meta_var::MetaVarEnv, Node};
15
16use bit_set::BitSet;
17use std::borrow::Cow;
18
19pub use kind::{kind_utils, KindMatcher, KindMatcherError};
20pub use node_match::NodeMatch;
21pub use pattern::{Pattern, PatternBuilder, PatternError, PatternNode};
22pub use text::{RegexMatcher, RegexMatcherError};
23
24pub trait Matcher {
28 fn match_node_with_env<'tree, D: Doc>(
32 &self,
33 _node: Node<'tree, D>,
34 _env: &mut Cow<MetaVarEnv<'tree, D>>,
35 ) -> Option<Node<'tree, D>>;
36
37 fn potential_kinds(&self) -> Option<BitSet> {
40 None
41 }
42
43 fn get_match_len<D: Doc>(&self, _node: Node<'_, D>) -> Option<usize> {
46 None
47 }
48}
49
50pub trait MatcherExt: Matcher {
54 fn match_node<'tree, D: Doc>(&self, node: Node<'tree, D>) -> Option<NodeMatch<'tree, D>> {
55 let mut env = Cow::Owned(MetaVarEnv::new());
57 let node = self.match_node_with_env(node, &mut env)?;
58 Some(NodeMatch::new(node, env.into_owned()))
59 }
60
61 fn find_node<'tree, D: Doc>(&self, node: Node<'tree, D>) -> Option<NodeMatch<'tree, D>> {
62 for n in node.dfs() {
63 if let Some(ret) = self.match_node(n.clone()) {
64 return Some(ret);
65 }
66 }
67 None
68 }
69}
70
71impl<T> MatcherExt for T where T: Matcher {}
72
73impl Matcher for str {
74 fn match_node_with_env<'tree, D: Doc>(
75 &self,
76 node: Node<'tree, D>,
77 env: &mut Cow<MetaVarEnv<'tree, D>>,
78 ) -> Option<Node<'tree, D>> {
79 let pattern = Pattern::new(self, node.lang().clone());
80 pattern.match_node_with_env(node, env)
81 }
82
83 fn get_match_len<D: Doc>(&self, node: Node<'_, D>) -> Option<usize> {
84 let pattern = Pattern::new(self, node.lang().clone());
85 pattern.get_match_len(node)
86 }
87}
88
89impl<T> Matcher for &T
90where
91 T: Matcher + ?Sized,
92{
93 fn match_node_with_env<'tree, D: Doc>(
94 &self,
95 node: Node<'tree, D>,
96 env: &mut Cow<MetaVarEnv<'tree, D>>,
97 ) -> Option<Node<'tree, D>> {
98 (**self).match_node_with_env(node, env)
99 }
100
101 fn potential_kinds(&self) -> Option<BitSet> {
102 (**self).potential_kinds()
103 }
104
105 fn get_match_len<D: Doc>(&self, node: Node<'_, D>) -> Option<usize> {
106 (**self).get_match_len(node)
107 }
108}
109
110pub struct MatchAll;
111impl Matcher for MatchAll {
112 fn match_node_with_env<'tree, D: Doc>(
113 &self,
114 node: Node<'tree, D>,
115 _env: &mut Cow<MetaVarEnv<'tree, D>>,
116 ) -> Option<Node<'tree, D>> {
117 Some(node)
118 }
119
120 fn potential_kinds(&self) -> Option<BitSet> {
121 None
123 }
124}
125
126pub struct MatchNone;
127impl Matcher for MatchNone {
128 fn match_node_with_env<'tree, D: Doc>(
129 &self,
130 _node: Node<'tree, D>,
131 _env: &mut Cow<MetaVarEnv<'tree, D>>,
132 ) -> Option<Node<'tree, D>> {
133 None
134 }
135
136 fn potential_kinds(&self) -> Option<BitSet> {
137 Some(BitSet::new())
139 }
140}