Skip to main content

sift_core/search/
matcher.rs

1use grep_matcher::LineTerminator;
2use grep_regex::{RegexMatcher, RegexMatcherBuilder};
3use grep_searcher::{BinaryDetection, Searcher, SearcherBuilder};
4
5use super::{CaseMode, CompiledSearch};
6
7impl CompiledSearch {
8    /// # Errors
9    /// Returns an error if pattern compilation fails.
10    pub fn build_matcher(&self) -> crate::Result<RegexMatcher> {
11        let mut builder = RegexMatcherBuilder::new();
12        builder.multi_line(true);
13        match self.opts.case_mode {
14            CaseMode::Sensitive => {}
15            CaseMode::Insensitive => {
16                builder.case_insensitive(true);
17            }
18            CaseMode::Smart => {
19                builder.case_smart(true);
20            }
21        }
22        builder.fixed_strings(self.opts.fixed_strings());
23        if self.opts.word_regexp() {
24            builder.word(true);
25        }
26        if self.opts.line_regexp() {
27            builder.whole_line(true);
28        }
29        builder.line_terminator(Some(b'\n'));
30        builder.ban_byte(Some(b'\x00'));
31        builder
32            .build_many(&self.patterns)
33            .map_err(|e| crate::Error::RegexBuild(e.to_string()))
34    }
35
36    pub(super) fn build_searcher(&self, line_number: bool, max_matches: Option<usize>) -> Searcher {
37        let mut builder = SearcherBuilder::new();
38        builder
39            .binary_detection(BinaryDetection::quit(b'\x00'))
40            .line_terminator(LineTerminator::byte(b'\n'))
41            .invert_match(self.opts.invert_match())
42            .line_number(line_number)
43            .max_matches(max_matches.map(|n| n as u64));
44        builder.build()
45    }
46}