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