pub fn filter_by_wildcard(pattern: &str, items: &[String]) -> Vec<String> {
items
.iter()
.filter(|item| matches_wildcard(pattern, item))
.cloned()
.collect()
}
fn matches_wildcard(pattern: &str, text: &str) -> bool {
let pattern_chars: Vec<char> = pattern.chars().collect();
let text_chars: Vec<char> = text.chars().collect();
matches_recursive(&pattern_chars, &text_chars, 0, 0)
}
fn matches_recursive(pattern: &[char], text: &[char], p_idx: usize, t_idx: usize) -> bool {
if p_idx == pattern.len() && t_idx == text.len() {
return true; }
if p_idx == pattern.len() {
return false; }
match pattern[p_idx] {
'*' => {
if matches_recursive(pattern, text, p_idx + 1, t_idx) {
return true;
}
for i in t_idx..text.len() {
if matches_recursive(pattern, text, p_idx + 1, i + 1) {
return true;
}
}
false
}
'?' => {
if t_idx < text.len() {
matches_recursive(pattern, text, p_idx + 1, t_idx + 1)
} else {
false
}
}
c => {
if t_idx < text.len() && text[t_idx] == c {
matches_recursive(pattern, text, p_idx + 1, t_idx + 1)
} else {
false
}
}
}
}