use crate::ast::SelectorPattern;
pub fn detection_name_matches(pattern: &str, name: &str) -> bool {
if pattern == "*" {
return true;
}
if let Some(prefix) = pattern.strip_suffix('*') {
return name.starts_with(prefix);
}
if let Some(suffix) = pattern.strip_prefix('*') {
return name.ends_with(suffix);
}
if let Some((prefix, suffix)) = pattern.split_once('*') {
return name.starts_with(prefix) && name.ends_with(suffix);
}
pattern == name
}
impl SelectorPattern {
pub fn matches_detection_name(&self, name: &str) -> bool {
match self {
SelectorPattern::Them => !name.starts_with('_'),
SelectorPattern::Pattern(pat) => detection_name_matches(pat, name),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn star_only_matches_anything() {
assert!(detection_name_matches("*", "anything"));
assert!(detection_name_matches("*", ""));
}
#[test]
fn star_suffix_matches_prefix() {
assert!(detection_name_matches("selection_*", "selection_main"));
assert!(detection_name_matches("selection_*", "selection_"));
assert!(!detection_name_matches("selection_*", "filter_main"));
}
#[test]
fn star_prefix_matches_suffix() {
assert!(detection_name_matches("*_main", "selection_main"));
assert!(!detection_name_matches("*_main", "selection_alt"));
}
#[test]
fn star_middle_matches_prefix_and_suffix() {
assert!(detection_name_matches("sel*main", "selection_main"));
assert!(!detection_name_matches("sel*main", "filter_main"));
assert!(!detection_name_matches("sel*main", "selection_alt"));
}
#[test]
fn exact_match_without_star() {
assert!(detection_name_matches("selection", "selection"));
assert!(!detection_name_matches("selection", "filter"));
assert!(!detection_name_matches("selection", "selection_main"));
}
#[test]
fn underscore_pattern_is_literal() {
assert!(detection_name_matches("_helper", "_helper"));
assert!(!detection_name_matches("_helper", "helper"));
}
#[test]
fn selector_pattern_them_skips_underscore_names() {
let them = SelectorPattern::Them;
assert!(them.matches_detection_name("selection"));
assert!(!them.matches_detection_name("_internal"));
}
#[test]
fn selector_pattern_pattern_uses_glob() {
let pat = SelectorPattern::Pattern("selection_*".to_string());
assert!(pat.matches_detection_name("selection_main"));
assert!(!pat.matches_detection_name("filter_main"));
let internal = SelectorPattern::Pattern("_internal".to_string());
assert!(internal.matches_detection_name("_internal"));
}
}