Fix ~ improve portability of path manipulation

This commit is contained in:
Roy Ivy III
2020-01-21 21:18:36 -06:00
parent 18510130d8
commit 7c34389aea
2 changed files with 24 additions and 12 deletions
+4 -1
View File
@@ -159,7 +159,10 @@ pub fn format_string(
) -> String { ) -> String {
let printable_name = { let printable_name = {
if display_data.short_paths { if display_data.short_paths {
dir_name.split('/').last().unwrap_or(dir_name) dir_name
.split(std::path::is_separator)
.last()
.unwrap_or(dir_name)
} else { } else {
dir_name dir_name
} }
+20 -11
View File
@@ -38,8 +38,9 @@ impl PartialEq for Node {
} }
pub fn is_a_parent_of(parent: &str, child: &str) -> bool { pub fn is_a_parent_of(parent: &str, child: &str) -> bool {
(child.starts_with(parent) && child.chars().nth(parent.chars().count()) == Some('/')) let path_parent = std::path::Path::new(parent);
|| parent == "/" let path_child = std::path::Path::new(child);
(path_child.starts_with(path_parent) && !path_parent.starts_with(path_child))
} }
pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> { pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> {
@@ -47,7 +48,7 @@ pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> {
let mut to_remove: Vec<String> = Vec::with_capacity(filenames.len()); let mut to_remove: Vec<String> = Vec::with_capacity(filenames.len());
for t in filenames { for t in filenames {
let top_level_name = strip_end_slash(t); let top_level_name = strip_trailing_curdirs(t);
let mut can_add = true; let mut can_add = true;
for tt in top_level_names.iter() { for tt in top_level_names.iter() {
@@ -61,7 +62,7 @@ pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> {
top_level_names.retain(|tr| to_remove.binary_search(tr).is_err()); top_level_names.retain(|tr| to_remove.binary_search(tr).is_err());
to_remove.clear(); to_remove.clear();
if can_add { if can_add {
top_level_names.insert(strip_end_slash(t).to_owned()); top_level_names.insert(strip_trailing_curdirs(t).to_owned());
} }
} }
@@ -107,11 +108,13 @@ fn get_allowed_filesystems(top_level_names: &HashSet<String>) -> Option<HashSet<
Some(limit_filesystems) Some(limit_filesystems)
} }
pub fn strip_end_slash(mut new_name: &str) -> &str { pub fn strip_trailing_curdirs<P: AsRef<std::path::Path>>(path: P) -> std::string::String {
while (new_name.ends_with('/') || new_name.ends_with("/.")) && new_name.len() > 1 { // `Path.components()` normalizes the path (repeated separators, interior '.', and trailing slashes are removed); ref: <https://doc.rust-lang.org/std/path/struct.Path.html#method.components>
new_name = &new_name[..new_name.len() - 1]; path.as_ref()
} .components()
new_name .collect::<std::path::PathBuf>()
.to_string_lossy()
.to_string()
} }
fn examine_dir( fn examine_dir(
@@ -235,11 +238,12 @@ pub fn trim_deep_ones(
let mut result: Vec<(String, u64)> = Vec::with_capacity(input.len() * top_level_names.len()); let mut result: Vec<(String, u64)> = Vec::with_capacity(input.len() * top_level_names.len());
for name in top_level_names { for name in top_level_names {
let my_max_depth = name.matches('/').count() + max_depth as usize; let my_max_depth = name.matches(std::path::is_separator).count() + max_depth as usize;
let name_ref: &str = name.as_ref(); let name_ref: &str = name.as_ref();
for &(ref k, ref v) in input.iter() { for &(ref k, ref v) in input.iter() {
if k.starts_with(name_ref) && k.matches('/').count() <= my_max_depth { if k.starts_with(name_ref) && k.matches(std::path::is_separator).count() <= my_max_depth
{
result.push((k.clone(), *v)); result.push((k.clone(), *v));
} }
} }
@@ -300,6 +304,10 @@ mod tests {
fn test_is_a_parent_of() { fn test_is_a_parent_of() {
assert!(is_a_parent_of("/usr", "/usr/andy")); assert!(is_a_parent_of("/usr", "/usr/andy"));
assert!(is_a_parent_of("/usr", "/usr/andy/i/am/descendant")); assert!(is_a_parent_of("/usr", "/usr/andy/i/am/descendant"));
assert!(!is_a_parent_of("/usr", "/usr/."));
assert!(!is_a_parent_of("/usr", "/usr/"));
assert!(!is_a_parent_of("/usr", "/usr"));
assert!(!is_a_parent_of("/usr/", "/usr"));
assert!(!is_a_parent_of("/usr/andy", "/usr")); assert!(!is_a_parent_of("/usr/andy", "/usr"));
assert!(!is_a_parent_of("/usr/andy", "/usr/sibling")); assert!(!is_a_parent_of("/usr/andy", "/usr/sibling"));
} }
@@ -308,5 +316,6 @@ mod tests {
fn test_is_a_parent_of_root() { fn test_is_a_parent_of_root() {
assert!(is_a_parent_of("/", "/usr/andy")); assert!(is_a_parent_of("/", "/usr/andy"));
assert!(is_a_parent_of("/", "/usr")); assert!(is_a_parent_of("/", "/usr"));
assert!(!is_a_parent_of("/", "/"));
} }
} }