litcheck_filecheck/pattern/search/
mod.rs

1mod 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}