diff options
Diffstat (limited to 'crates/shirabe-external-packages/src/symfony/finder/glob.rs')
| -rw-r--r-- | crates/shirabe-external-packages/src/symfony/finder/glob.rs | 106 |
1 files changed, 100 insertions, 6 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/finder/glob.rs b/crates/shirabe-external-packages/src/symfony/finder/glob.rs index eb79147..fe5398f 100644 --- a/crates/shirabe-external-packages/src/symfony/finder/glob.rs +++ b/crates/shirabe-external-packages/src/symfony/finder/glob.rs @@ -4,11 +4,105 @@ pub struct Glob; impl Glob { - pub fn to_regex( - _glob: &str, - _strict_leading_dot: bool, - _strict_wildcard_slash: bool, - ) -> String { - todo!() + pub fn to_regex(glob: &str, strict_leading_dot: bool, strict_wildcard_slash: bool) -> String { + let delimiter = '#'; + let mut first_byte = true; + let mut escaping = false; + let mut in_curlies: i64 = 0; + let mut regex = String::new(); + let bytes = glob.as_bytes(); + let size_glob = bytes.len(); + let mut i = 0; + while i < size_glob { + let mut car = (bytes[i] as char).to_string(); + if first_byte && strict_leading_dot && car != "." { + regex.push_str("(?=[^\\.])"); + } + + first_byte = car == "/"; + + if first_byte + && strict_wildcard_slash + && i + 2 < size_glob + && bytes[i + 1] == b'*' + && bytes[i + 2] == b'*' + && (i + 3 >= size_glob || bytes[i + 3] == b'/') + { + let mut new_car = String::from("[^/]++/"); + if i + 3 >= size_glob { + new_car.push('?'); + } + + if strict_leading_dot { + new_car = format!("(?=[^\\.]){}", new_car); + } + + new_car = format!("/(?:{})*", new_car); + i += 2 + usize::from(i + 3 < size_glob); + + if delimiter == '/' { + new_car = new_car.replace('/', "\\/"); + } + + car = new_car; + } + + if car == delimiter.to_string() + || car == "." + || car == "(" + || car == ")" + || car == "|" + || car == "+" + || car == "^" + || car == "$" + { + regex.push('\\'); + regex.push_str(&car); + } else if car == "*" { + regex.push_str(if escaping { + "\\*" + } else if strict_wildcard_slash { + "[^/]*" + } else { + ".*" + }); + } else if car == "?" { + regex.push_str(if escaping { + "\\?" + } else if strict_wildcard_slash { + "[^/]" + } else { + "." + }); + } else if car == "{" { + regex.push_str(if escaping { "\\{" } else { "(" }); + if !escaping { + in_curlies += 1; + } + } else if car == "}" && in_curlies > 0 { + regex.push_str(if escaping { "}" } else { ")" }); + if !escaping { + in_curlies -= 1; + } + } else if car == "," && in_curlies > 0 { + regex.push_str(if escaping { "," } else { "|" }); + } else if car == "\\" { + if escaping { + regex.push_str("\\\\"); + escaping = false; + } else { + escaping = true; + } + + i += 1; + continue; + } else { + regex.push_str(&car); + } + escaping = false; + i += 1; + } + + format!("{delimiter}^{regex}${delimiter}") } } |
