(text: &str, pattern: &str)
| 4 | use crate::types::FirewallRule; |
| 5 | |
| 6 | pub fn matches_wildcard(text: &str, pattern: &str) -> bool { |
| 7 | let text_lower = text.to_lowercase(); |
| 8 | let pattern_lower = pattern.to_lowercase(); |
| 9 | |
| 10 | if !pattern_lower.contains('*') { |
| 11 | return text_lower == pattern_lower; |
| 12 | } |
| 13 | |
| 14 | let parts: Vec<&str> = pattern_lower.split('*').collect(); |
| 15 | if !parts[0].is_empty() && !text_lower.starts_with(parts[0]) { |
| 16 | return false; |
| 17 | } |
| 18 | |
| 19 | let mut position = parts[0].len(); |
| 20 | let suffix = *parts.last().unwrap_or(&""); |
| 21 | let end = if suffix.is_empty() { |
| 22 | text_lower.len() |
| 23 | } else { |
| 24 | if !text_lower.ends_with(suffix) { |
| 25 | return false; |
| 26 | } |
| 27 | text_lower.len() - suffix.len() |
| 28 | }; |
| 29 | |
| 30 | for part in &parts[1..parts.len().saturating_sub(1)] { |
| 31 | if part.is_empty() { |
| 32 | continue; |
| 33 | } |
| 34 | match text_lower.get(position..end).and_then(|s| s.find(part)) { |
| 35 | Some(index) => position += index + part.len(), |
| 36 | None => return false, |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | position <= end |
| 41 | } |
| 42 | |
| 43 | fn matches_optional_wildcard(actual: &Option<String>, filter: &Option<String>) -> bool { |
| 44 | match filter { |
no test coverage detected