use camino::{Utf8Component, Utf8Path};
pub(super) fn escape_glob_literal_path(path: &Utf8Path) -> String {
let separator = std::path::MAIN_SEPARATOR;
let mut escaped = String::new();
let mut needs_separator = false;
for component in path.components() {
match component {
Utf8Component::Prefix(prefix) => {
escaped.push_str(prefix.as_str());
needs_separator = false;
}
Utf8Component::RootDir => {
escaped.push(separator);
needs_separator = false;
}
Utf8Component::CurDir => {
append_glob_path_component(&mut escaped, ".", separator, &mut needs_separator);
}
Utf8Component::ParentDir => {
append_glob_path_component(&mut escaped, "..", separator, &mut needs_separator);
}
Utf8Component::Normal(name) => {
let literal = glob::Pattern::escape(name);
append_glob_path_component(&mut escaped, &literal, separator, &mut needs_separator);
}
}
}
escaped
}
fn append_glob_path_component(
path: &mut String,
component: &str,
separator: char,
needs_separator: &mut bool,
) {
if *needs_separator {
path.push(separator);
}
path.push_str(component);
*needs_separator = true;
}
#[cfg(all(test, windows))]
mod tests {
use super::escape_glob_literal_path;
use camino::Utf8Path;
#[test]
fn preserves_verbatim_prefix() {
let path = Utf8Path::new(r"\\?\C:\work\literal[ab]base");
assert_eq!(
escape_glob_literal_path(path),
r"\\?\C:\work\literal[[]ab[]]base"
);
}
}