rust-matchers: add function to generate a regex matcher function
This function will be used to help build the upcoming `IncludeMatcher`. While
Re2 is still used and behind a feature flag, this function returns an error
meant for fallback in the default case.
Differential Revision: https://phab.mercurial-scm.org/D7922
--- a/rust/hg-core/src/lib.rs Tue Mar 10 16:04:30 2020 +0100
+++ b/rust/hg-core/src/lib.rs Fri Jan 17 11:29:33 2020 +0100
@@ -126,6 +126,9 @@
/// Needed a pattern that can be turned into a regex but got one that
/// can't. This should only happen through programmer error.
NonRegexPattern(IgnorePattern),
+ /// This is temporary, see `re2/mod.rs`.
+ /// This will cause a fallback to Python.
+ Re2NotInstalled,
}
impl ToString for PatternError {
@@ -148,6 +151,10 @@
PatternError::NonRegexPattern(pattern) => {
format!("'{:?}' cannot be turned into a regex", pattern)
}
+ PatternError::Re2NotInstalled => {
+ "Re2 is not installed, cannot use regex functionality."
+ .to_string()
+ }
}
}
}
--- a/rust/hg-core/src/matchers.rs Tue Mar 10 16:04:30 2020 +0100
+++ b/rust/hg-core/src/matchers.rs Fri Jan 17 11:29:33 2020 +0100
@@ -7,7 +7,12 @@
//! Structs and types for matching files and directories.
-use crate::{utils::hg_path::HgPath, DirsMultiset, DirstateMapError};
+#[cfg(feature = "with-re2")]
+use crate::re2::Re2;
+use crate::{
+ filepatterns::PatternResult, utils::hg_path::HgPath, DirsMultiset,
+ DirstateMapError, PatternError,
+};
use std::collections::HashSet;
use std::iter::FromIterator;
use std::ops::Deref;
@@ -215,6 +220,26 @@
true
}
}
+
+#[cfg(feature = "with-re2")]
+/// Returns a function that matches an `HgPath` against the given regex
+/// pattern.
+///
+/// This can fail when the pattern is invalid or not supported by the
+/// underlying engine `Re2`, for instance anything with back-references.
+fn re_matcher(
+ pattern: &[u8],
+) -> PatternResult<impl Fn(&HgPath) -> bool + Sync> {
+ let regex = Re2::new(pattern);
+ let regex = regex.map_err(|e| PatternError::UnsupportedSyntax(e))?;
+ Ok(move |path: &HgPath| regex.is_match(path.as_bytes()))
+}
+
+#[cfg(not(feature = "with-re2"))]
+fn re_matcher(_: &[u8]) -> PatternResult<Box<dyn Fn(&HgPath) -> bool + Sync>> {
+ Err(PatternError::Re2NotInstalled)
+}
+
#[cfg(test)]
mod tests {
use super::*;