litcheck_filecheck/pattern/matcher/
mod.rs1mod matchers;
2mod result;
3
4pub use self::matchers::*;
5pub use self::result::{CaptureInfo, MatchInfo, MatchResult, MatchType};
6
7use crate::common::*;
8
9pub type AnyMatcher<'a> = Box<dyn DynMatcher + 'a>;
10
11pub type AnyMatcherMut<'a> = Box<dyn DynMatcherMut + 'a>;
12
13pub trait Matcher: MatcherMut {
16 fn try_match<'input, 'context, C>(
20 &self,
21 input: Input<'input>,
22 context: &C,
23 ) -> DiagResult<MatchResult<'input>>
24 where
25 C: Context<'input, 'context> + ?Sized;
26}
27impl<'a, M> Matcher for &'a M
28where
29 M: ?Sized + Matcher,
30{
31 fn try_match<'input, 'context, C>(
32 &self,
33 input: Input<'input>,
34 context: &C,
35 ) -> DiagResult<MatchResult<'input>>
36 where
37 C: Context<'input, 'context> + ?Sized,
38 {
39 <M as Matcher>::try_match(self, input, context)
40 }
41}
42
43pub trait DynMatcher: DynMatcherMut {
44 fn try_match_dyn<'input>(
45 &self,
46 input: Input<'input>,
47 context: &dyn Context<'input, '_>,
48 ) -> DiagResult<MatchResult<'input>>;
49}
50impl<M> DynMatcher for M
51where
52 M: Matcher,
53{
54 fn try_match_dyn<'input>(
55 &self,
56 input: Input<'input>,
57 context: &dyn Context<'input, '_>,
58 ) -> DiagResult<MatchResult<'input>> {
59 self.try_match(input, context)
60 }
61}
62
63pub trait MatcherMut: fmt::Debug + Spanned {
70 fn try_match_mut<'input, 'context, C>(
74 &self,
75 input: Input<'input>,
76 context: &mut C,
77 ) -> DiagResult<MatchResult<'input>>
78 where
79 C: Context<'input, 'context> + ?Sized;
80}
81impl<'a, M> MatcherMut for &'a M
82where
83 M: ?Sized + MatcherMut,
84{
85 fn try_match_mut<'input, 'context, C>(
86 &self,
87 input: Input<'input>,
88 context: &mut C,
89 ) -> DiagResult<MatchResult<'input>>
90 where
91 C: Context<'input, 'context> + ?Sized,
92 {
93 <M as MatcherMut>::try_match_mut(self, input, context)
94 }
95}
96impl<'a> MatcherMut for (dyn DynMatcher + 'a) {
97 #[inline]
98 fn try_match_mut<'input, 'context, C>(
99 &self,
100 input: Input<'input>,
101 context: &mut C,
102 ) -> DiagResult<MatchResult<'input>>
103 where
104 C: Context<'input, 'context> + ?Sized,
105 {
106 let passthrough = context.protect();
107 self.try_match_dyn(input, &passthrough)
108 }
109}
110impl<'a> MatcherMut for Box<dyn DynMatcher + 'a> {
111 #[inline]
112 fn try_match_mut<'input, 'context, C>(
113 &self,
114 input: Input<'input>,
115 context: &mut C,
116 ) -> DiagResult<MatchResult<'input>>
117 where
118 C: Context<'input, 'context> + ?Sized,
119 {
120 (**self).try_match_mut(input, context)
121 }
122}
123
124pub trait DynMatcherMut: fmt::Debug + Spanned {
125 fn try_match_mut_dyn<'input>(
126 &self,
127 input: Input<'input>,
128 context: &mut dyn Context<'input, '_>,
129 ) -> DiagResult<MatchResult<'input>>;
130}
131impl<M> DynMatcherMut for M
132where
133 M: MatcherMut,
134{
135 fn try_match_mut_dyn<'input>(
136 &self,
137 input: Input<'input>,
138 context: &mut dyn Context<'input, '_>,
139 ) -> DiagResult<MatchResult<'input>> {
140 self.try_match_mut(input, context)
141 }
142}
143impl<'a> MatcherMut for (dyn DynMatcherMut + 'a) {
144 #[inline]
145 fn try_match_mut<'input, 'context, C>(
146 &self,
147 input: Input<'input>,
148 context: &mut C,
149 ) -> DiagResult<MatchResult<'input>>
150 where
151 C: Context<'input, 'context> + ?Sized,
152 {
153 let mut passthrough = context.protect();
154 let result = self.try_match_mut_dyn(input, &mut passthrough)?;
155 if result.is_ok() {
156 passthrough.save();
157 }
158 Ok(result)
159 }
160}
161impl<'a> MatcherMut for Box<dyn DynMatcherMut + 'a> {
162 #[inline]
163 fn try_match_mut<'input, 'context, C>(
164 &self,
165 input: Input<'input>,
166 context: &mut C,
167 ) -> DiagResult<MatchResult<'input>>
168 where
169 C: Context<'input, 'context> + ?Sized,
170 {
171 (**self).try_match_mut(input, context)
172 }
173}