Refactor regex operations

This commit is contained in:
Oliver Hamlet
2025-05-08 14:37:19 +01:00
parent 531210afac
commit 5cb4c9f165
3 changed files with 59 additions and 29 deletions
+29 -17
View File
@@ -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::<u32>() {
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::<u32>() {
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();
+15 -3
View File
@@ -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<Self, ParseMetadataError> {
let mapping = as_mapping(value, YamlObjectType::PluginMetadata)?;
+15 -9
View File
@@ -434,15 +434,7 @@ fn extract_version(description: &str) -> Result<Option<String>, Box<RegexImplErr
});
for regex in &*VERSION_REGEXES {
let version = regex
.captures(description)?
.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);
let version = find_captured_text(regex, description)?;
if version.is_some() {
return Ok(version);
@@ -452,6 +444,20 @@ fn extract_version(description: &str) -> Result<Option<String>, Box<RegexImplErr
Ok(None)
}
fn find_captured_text(regex: &Regex, text: &str) -> Result<Option<String>, Box<RegexImplError>> {
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::*;