Simple glob matching (supports * and **) Matching rules: - `*` matches any characters in filename (excluding `/`) - `**` matches any path (including `/`) - `*.ext` matches any file ending with `.ext` (any depth) - `dir/**/*.ext` matches `.ext` files at any depth under dir
(&self, pattern: &str, text: &str)
| 210 | /// - `*.ext` matches any file ending with `.ext` (any depth) |
| 211 | /// - `dir/**/*.ext` matches `.ext` files at any depth under dir |
| 212 | fn glob_match(&self, pattern: &str, text: &str) -> bool { |
| 213 | // Normalize Windows backslashes to forward slashes for consistent matching |
| 214 | let text = text.replace('\\', "/"); |
| 215 | |
| 216 | // Special handling: if pattern starts with * and has no /, |
| 217 | // match file suffix. e.g., "*.rs" should match "src/main.rs" |
| 218 | if pattern.starts_with('*') && !pattern.contains('/') { |
| 219 | let suffix = &pattern[1..]; // Remove leading * |
| 220 | return text.ends_with(suffix); |
| 221 | } |
| 222 | |
| 223 | // Convert glob to regex |
| 224 | let regex_pattern = pattern |
| 225 | .replace('.', r"\.") |
| 226 | .replace("**/", "__DOUBLE_STAR_SLASH__") |
| 227 | .replace("**", "__DOUBLE_STAR__") |
| 228 | .replace('*', "[^/]*") |
| 229 | .replace("__DOUBLE_STAR_SLASH__", "(?:.*/)?") // **/ matches zero or more directories |
| 230 | .replace("__DOUBLE_STAR__", ".*"); |
| 231 | |
| 232 | let regex_pattern = format!("^{}$", regex_pattern); |
| 233 | |
| 234 | if let Ok(re) = regex::Regex::new(®ex_pattern) { |
| 235 | re.is_match(&text) |
| 236 | } else { |
| 237 | text == pattern |
| 238 | } |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | #[cfg(test)] |
no test coverage detected