pub fn glob_matches(pattern: &str, input: &str) -> bool {
glob_matches_impl(pattern.as_bytes(), input.as_bytes(), false)
}
pub fn glob_matches_path(pattern: &str, input: &str) -> bool {
glob_matches_impl(pattern.as_bytes(), input.as_bytes(), true)
}
fn glob_matches_impl(pattern: &[u8], input: &[u8], slash_sensitive: bool) -> bool {
let mut pi = 0;
let mut ii = 0;
let mut star_pi = usize::MAX;
let mut star_ii = 0;
let mut dstar_pi = usize::MAX;
let mut dstar_ii = 0;
while ii < input.len() {
if pi + 1 < pattern.len() && pattern[pi] == b'*' && pattern[pi + 1] == b'*' {
dstar_pi = pi;
dstar_ii = ii;
pi += 2;
if pi < pattern.len() && pattern[pi] == b'/' {
pi += 1;
}
continue;
} else if pi < pattern.len() && pattern[pi] == b'*' {
star_pi = pi;
star_ii = ii;
pi += 1;
continue;
} else if pi < pattern.len() && (pattern[pi] == input[ii] || pattern[pi] == b'?') {
pi += 1;
ii += 1;
continue;
}
if star_pi != usize::MAX && (!slash_sensitive || input[star_ii] != b'/') {
star_ii += 1;
ii = star_ii;
pi = star_pi + 1;
continue;
}
if dstar_pi != usize::MAX {
dstar_ii += 1;
ii = dstar_ii;
pi = dstar_pi + 2;
if pi < pattern.len() && pattern[pi] == b'/' {
pi += 1;
}
continue;
}
return false;
}
while pi < pattern.len() && pattern[pi] == b'*' {
pi += 1;
}
pi == pattern.len()
}
#[cfg(test)]
#[path = "glob_tests.rs"]
mod tests;