litcheck_filecheck/pattern/search/
mod.rs1mod aho_corasick;
2mod r#default;
3mod pattern_set;
4mod regex;
5mod substring_set;
6
7pub use self::aho_corasick::AhoCorasickSearcher;
8pub use self::r#default::DefaultSearcher;
9pub use self::pattern_set::PatternSetSearcher;
10pub use self::regex::RegexSearcher;
11pub use self::substring_set::SubstringSetSearcher;
12pub use crate::pattern::matcher::RegexSetSearcher;
13
14use std::{fmt, ops::RangeBounds};
15
16use crate::common::{
17 Context, DiagResult, MatchResult, PatternIdentifier, Range, SourceId, SourceSpan,
18};
19
20pub trait Searcher {
21 type Input: Input;
22 type Match: Match;
23 type MatchError: std::error::Error;
24
25 fn input(&self) -> &Self::Input;
26 fn last_match_end(&self) -> Option<usize>;
27 fn set_last_match_end(&mut self, end: usize);
28 fn set_range<R>(&mut self, range: R)
29 where
30 R: RangeBounds<usize>;
31 fn advance<F>(&mut self, finder: F) -> Option<Self::Match>
32 where
33 F: FnMut(&Self::Input) -> Result<Option<Self::Match>, Self::MatchError>,
34 {
35 match self.try_advance(finder) {
36 Ok(m) => m,
37 Err(err) => panic!("unexpected search error: {}", err),
38 }
39 }
40 fn try_advance<F>(&mut self, finder: F) -> Result<Option<Self::Match>, Self::MatchError>
41 where
42 F: FnMut(&Self::Input) -> Result<Option<Self::Match>, Self::MatchError>;
43
44 fn handle_overlapping_empty_match<F>(
45 &mut self,
46 m: Self::Match,
47 finder: F,
48 ) -> Result<Option<Self::Match>, Self::MatchError>
49 where
50 F: FnMut(&Self::Input) -> Result<Option<Self::Match>, Self::MatchError>;
51}
52
53pub trait PatternSearcher<'input> {
54 type Input: Input;
55 type PatternID: PatternIdentifier;
56
57 fn input(&self) -> &Self::Input;
58 fn last_match_end(&self) -> Option<usize>;
59 fn set_last_match_end(&mut self, end: usize);
60 fn patterns_len(&self) -> usize;
61 fn pattern_span(&self, id: Self::PatternID) -> SourceSpan;
62 fn try_match_next<'context, C>(&mut self, context: &mut C) -> DiagResult<MatchResult<'input>>
63 where
64 C: Context<'input, 'context> + ?Sized;
65}
66
67pub trait Match: fmt::Debug {
68 type PatternID: PatternIdentifier;
69
70 fn is_empty(&self) -> bool;
71 fn pattern(&self) -> Self::PatternID;
72 fn end(&self) -> usize;
73 fn range(&self) -> Range<usize>;
74}
75
76pub trait Input: fmt::Debug {
77 fn source_id(&self) -> SourceId;
78 fn buffer(&self) -> &[u8];
79 fn anchored(&self) -> bool;
80 fn range(&self) -> Range<usize>;
81 fn start(&self) -> usize;
82 fn set_start(&mut self, start: usize);
83 fn set_range(&mut self, range: Range<usize>);
84 fn as_input(&self) -> crate::common::Input<'_> {
85 crate::common::Input::new(self.source_id(), self.buffer(), false)
86 .anchored(self.anchored())
87 .bounded(self.range())
88 }
89}
90
91impl<'a> Input for crate::common::Input<'a> {
92 #[inline(always)]
93 fn source_id(&self) -> SourceId {
94 crate::common::Input::source_id(self)
95 }
96 #[inline(always)]
97 fn buffer(&self) -> &[u8] {
98 crate::common::Input::buffer(self)
99 }
100 #[inline(always)]
101 fn anchored(&self) -> bool {
102 self.is_anchored()
103 }
104 #[inline(always)]
105 fn range(&self) -> Range<usize> {
106 self.bounds()
107 }
108 #[inline(always)]
109 fn start(&self) -> usize {
110 crate::common::Input::start(self)
111 }
112 #[inline(always)]
113 fn set_start(&mut self, start: usize) {
114 crate::common::Input::set_start(self, start)
115 }
116 #[inline(always)]
117 fn set_range(&mut self, range: Range<usize>) {
118 crate::common::Input::set_bounds(self, range)
119 }
120}