pub fn matches_pattern<T: AsRef<str>>(value: T, pattern: &str) -> bool {
let value = value.as_ref();
if pattern.contains('*') {
let parts: Vec<&str> = pattern.split('*').collect();
if pattern.ends_with('*') && parts.len() == 2 {
return value.starts_with(parts[0]);
}
if pattern.starts_with('*') && parts.len() == 2 {
return value.ends_with(parts[1]);
}
if pattern.starts_with('*') && pattern.ends_with('*') && parts.len() == 3 {
return value.contains(parts[1]);
}
} else {
return value.to_lowercase().contains(&pattern.to_lowercase());
}
value == pattern
}
pub fn filter_items<'a, T, F>(items: &'a [T], pattern: Option<&str>, extractor: F) -> Vec<&'a T>
where
F: Fn(&T) -> &str,
{
match pattern {
Some(pattern) => items
.iter()
.filter(|item| matches_pattern(extractor(item), pattern))
.collect(),
None => items.iter().collect(),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(PartialEq, Debug)]
struct TestItem {
name: String,
category: String,
count: i32,
}
#[test]
fn test_matches_pattern() {
assert!(matches_pattern("hello", "hello"));
assert!(matches_pattern("hello world", "hello"));
assert!(matches_pattern("Hello World", "hello"));
assert!(matches_pattern("hello world", "hello*"));
assert!(matches_pattern("hello world", "*world"));
assert!(matches_pattern("hello world", "*lo wor*"));
assert!(!matches_pattern("hello", "world"));
assert!(!matches_pattern("hello", "hello world"));
}
#[test]
fn test_filter_items() {
let items = vec![
TestItem {
name: "Table1".to_string(),
category: "Data".to_string(),
count: 10,
},
TestItem {
name: "UserEvents".to_string(),
category: "Events".to_string(),
count: 20,
},
TestItem {
name: "EventLog".to_string(),
category: "Events".to_string(),
count: 30,
},
TestItem {
name: "Settings".to_string(),
category: "Config".to_string(),
count: 40,
},
];
let filtered = filter_items(&items, Some("event"), |item| &item.name);
assert_eq!(filtered.len(), 2);
assert!(filtered.contains(&&items[1])); assert!(filtered.contains(&&items[2]));
let filtered = filter_items(&items, Some("events"), |item| &item.category);
assert_eq!(filtered.len(), 2);
assert!(filtered.contains(&&items[1])); assert!(filtered.contains(&&items[2]));
let filtered = filter_items(&items, Some("*Log"), |item| &item.name);
assert_eq!(filtered.len(), 1);
assert!(filtered.contains(&&items[2]));
let filtered = filter_items(&items, Some("NonExistent"), |item| &item.name);
assert_eq!(filtered.len(), 0);
let filtered = filter_items(&items, None, |item| &item.name);
assert_eq!(filtered.len(), items.len());
}
}