aboutsummaryrefslogtreecommitdiff
path: root/src/makefile/pattern.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/makefile/pattern.rs')
-rw-r--r--src/makefile/pattern.rs40
1 files changed, 17 insertions, 23 deletions
diff --git a/src/makefile/pattern.rs b/src/makefile/pattern.rs
index 733721e..2d5f46c 100644
--- a/src/makefile/pattern.rs
+++ b/src/makefile/pattern.rs
@@ -1,37 +1,31 @@
use regex::{Captures, Regex};
-fn compile_pattern(pattern: &str) -> Regex {
+fn compile_pattern(pattern: &str) -> anyhow::Result<Regex> {
let mut result = String::new();
for c in pattern.chars() {
- match c {
- // This is a nightmare, because we're escaping for regex syntax before we put
- // things into result.
-
- // We don't end with a backslash, so this is an unescaped wildcard.
- '%' if !result.ends_with(r"\\") => {
- result.push_str(r"(\w*)");
- }
-
- // We end with two backslashes, so this is an escaped backslash and then an
- // unescaped wildcard.
- '%' if result.ends_with(r"\\\\") => {
- result = result.strip_suffix(r"\\\\").unwrap().to_string();
+ if c == '%' {
+ if let Some(real_result) = result.strip_suffix(r"\\\\") {
+ // We end with two backslashes, so this is an escaped backslash and then an
+ // unescaped wildcard.
+ result = real_result.to_string();
result.push_str(r"\\(\w*)");
- }
-
- // We end with one backslash, so this is an escaped wildcard.
- '%' if result.ends_with(r"\\") => {
- result = result.strip_suffix(r"\\").unwrap().to_string();
+ } else if let Some(real_result) = result.strip_suffix(r"\\") {
+ // We end with one backslash, so this is an escaped wildcard.
+ result = real_result.to_string();
result.push('%');
+ } else {
+ // We don't end with a backslash, so this is an unescaped wildcard.
+ result.push_str(r"(\w*)");
}
- _ => result.push_str(&regex::escape(&c.to_string())),
+ } else {
+ result.push_str(&regex::escape(&c.to_string()));
}
}
- Regex::new(&result).expect("built invalid regex!")
+ Ok(Regex::new(&result)?)
}
-pub(crate) fn r#match<'a>(pattern: &str, text: &'a str) -> Option<Captures<'a>> {
- compile_pattern(pattern).captures(text)
+pub(crate) fn r#match<'a>(pattern: &str, text: &'a str) -> anyhow::Result<Option<Captures<'a>>> {
+ Ok(compile_pattern(pattern)?.captures(text))
}
#[cfg(test)]