From e1a0584936b3aa5ce971e875dec750d2ae937d2e Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Wed, 31 Mar 2021 12:51:11 -0600 Subject: massively upgrade error handling --- src/makefile/pattern.rs | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'src/makefile/pattern.rs') 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 { 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(®ex::escape(&c.to_string())), + } else { + result.push_str(®ex::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> { - compile_pattern(pattern).captures(text) +pub(crate) fn r#match<'a>(pattern: &str, text: &'a str) -> anyhow::Result>> { + Ok(compile_pattern(pattern)?.captures(text)) } #[cfg(test)] -- cgit v1.2.3