From 5cb4c9f16562eddd24cebea1c73e2d1d2ea99837 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 8 May 2025 14:37:19 +0100 Subject: [PATCH] Refactor regex operations --- src/metadata/message.rs | 46 +++++++++++++++++++++------------ src/metadata/plugin_metadata.rs | 18 ++++++++++--- src/plugin/mod.rs | 24 ++++++++++------- 3 files changed, 59 insertions(+), 29 deletions(-) diff --git a/src/metadata/message.rs b/src/metadata/message.rs index 68913d1a..19a27df2 100644 --- a/src/metadata/message.rs +++ b/src/metadata/message.rs @@ -319,21 +319,7 @@ impl TryFromYaml for Message { .expect("hardcoded Boost placeholder regex should be valid") }); - let result = BOOST_REGEX.replace_all(&mc.text, |captures: &Captures| { - match captures[1].parse::() { - Ok(i) if i > 0 => format!("{{{}}}", i - 1), - Ok(_) => { - logging::warn!("Found zero-indexed placeholder using Boost syntax in string \"{}\"", mc.text); - captures[0].to_string() - }, - Err(e) => { - logging::error!("Unexpected failure to parse Boost placeholder index \"{}\": {}", &captures[1], e); - captures[0].to_string() - } - } - }); - - if let Cow::Owned(text) = result { + if let Cow::Owned(text) = replace_all(&BOOST_REGEX, &mc.text) { mc.text = text.into_boxed_str(); } } @@ -354,10 +340,10 @@ impl TryFromYaml for Message { mc.text = mc.text.replace(&placeholder, sub).into_boxed_str(); } - if let Ok(Some(m)) = FMT_REGEX.find(&mc.text) { + if let Some(m) = find_match(&FMT_REGEX, &mc.text) { return Err(ParseMetadataError::new( value.span.start, - MetadataParsingErrorReason::MissingSubstitution(m.as_str().to_owned()), + MetadataParsingErrorReason::MissingSubstitution(m.to_owned()), )); } } @@ -373,6 +359,32 @@ impl TryFromYaml for Message { } } +fn replace_all<'a>(regex: &Regex, text: &'a str) -> Cow<'a, str> { + regex.replace_all(text, |captures: &Captures| { + match captures[1].parse::() { + Ok(i) if i > 0 => format!("{{{}}}", i - 1), + Ok(_) => { + logging::warn!( + "Found zero-indexed placeholder using Boost syntax in string \"{text}\"" + ); + captures[0].to_string() + } + Err(e) => { + logging::error!( + "Unexpected failure to parse Boost placeholder index \"{}\": {}", + &captures[1], + e + ); + captures[0].to_string() + } + } + }) +} + +fn find_match<'a>(regex: &Regex, text: &'a str) -> Option<&'a str> { + regex.find(text).ok().flatten().map(|m| m.as_str()) +} + impl EmitYaml for MessageContent { fn emit_yaml(&self, emitter: &mut YamlEmitter) { emitter.begin_map(); diff --git a/src/metadata/plugin_metadata.rs b/src/metadata/plugin_metadata.rs index 98a4f201..9803785e 100644 --- a/src/metadata/plugin_metadata.rs +++ b/src/metadata/plugin_metadata.rs @@ -274,9 +274,7 @@ impl PluginName { fn matches(&self, other_name: &str) -> bool { if let Some(regex) = &self.regex { - regex.is_match(other_name).inspect_err(|e| { - logging::error!("Encountered an error while trying to match the regex {} to the string {}: {}", regex.as_str(), other_name, e); - }).unwrap_or(false) + is_regex_match(regex, other_name) } else { unicase::eq(self.string.as_ref(), other_name) } @@ -382,6 +380,20 @@ fn replace_capturing_groups(regex_string: &str) -> Cow<'_, str> { } } +fn is_regex_match(regex: &Regex, string: &str) -> bool { + regex + .is_match(string) + .inspect_err(|e| { + logging::error!( + "Encountered an error while trying to match the regex {} to the string {}: {}", + regex.as_str(), + string, + e + ); + }) + .unwrap_or(false) +} + impl TryFromYaml for PluginMetadata { fn try_from_yaml(value: &MarkedYaml) -> Result { let mapping = as_mapping(value, YamlObjectType::PluginMetadata)?; diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index f02402fc..d36c2dca 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -434,15 +434,7 @@ fn extract_version(description: &str) -> Result, Box Result, Box Result, Box> { + let captured_text = regex + .captures(text)? + .iter() + .flat_map(|captures| captures.iter()) + .flatten() + .skip(1) // Skip the first capture as that's the whole regex. + .map(|m| m.as_str().trim()) + .find(|v| !v.is_empty()) + .map(str::to_owned); + + Ok(captured_text) +} + #[cfg(test)] mod tests { use super::*;