///|
fn comparable(path : String) -> String {
if @platform.is_windows() {
path.to_lower()
} else {
path
}
}
///|
fn canonical_path(path : String) -> String {
let separator = @path.sep.to_string()
let mut normalized = @path.Path(@platform.normalize_input_separators(path))
.normalize()
.to_string()
while normalized.has_suffix(separator) {
let parent = @path.Path(normalized).dirname().to_string()
if comparable(parent) == comparable(normalized) {
break
}
normalized = normalized[:normalized.length() - separator.length()].to_owned()
}
normalized
}
///|
fn is_filesystem_root(path : String) -> Bool {
let normalized = canonical_path(path)
let value = @path.Path(normalized)
value.is_absolute() &&
comparable(canonical_path(value.dirname().to_string())) ==
comparable(normalized)
}
///|
/// GNU rm rejects final . and .. components, and preserves the filesystem root
/// by default. An explicitly named working directory is not an extra policy.
fn protects_removal_operand(
path : String,
preserve_root~ : Bool = true,
) -> Bool {
let normalized = if @platform.is_windows() {
path.replace_all(old="\\", new="/")
} else {
path
}
let mut end = normalized.length()
while end > 0 && normalized[end - 1] == '/' {
end -= 1
}
let pieces = normalized[:end].split("/").collect()
let final_component = pieces.last().unwrap_or("")
final_component == "." ||
final_component == ".." ||
(preserve_root && is_filesystem_root(path))
}