nushell/crates/nu-parser/src/path.rs
Kevin Del Castillo 928188b18e
Redesign custom canonicalize, enable multiple dots expansion earlier. (#1588)
* Expand n dots early where tilde was also expanded.

* Remove normalize, not needed.
New function absolutize, doesn't follow links neither checks existence.
Renamed canonicalize_existing to canonicalize, works as expected.

* Remove normalize usages, change canonicalize.

* Treat strings as paths
2020-04-16 11:29:22 +12:00

53 lines
1.4 KiB
Rust

use std::path::{Component, Path, PathBuf};
fn expand_ndots(path: &str) -> String {
let path = Path::new(path);
let mut expanded = PathBuf::new();
for component in path.components() {
match component {
Component::Normal(normal) => {
if let Some(normal) = normal.to_str() {
if normal.chars().all(|c| c == '.') {
for _ in 0..(normal.len() - 1) {
expanded.push("..");
}
} else {
expanded.push(normal);
}
} else {
expanded.push(normal);
}
}
c => expanded.push(c.as_os_str()),
}
}
expanded.to_string_lossy().to_string()
}
pub fn expand_path(path: &str) -> String {
let tilde_expansion = shellexpand::tilde(path);
expand_ndots(&tilde_expansion)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn expand_in_relative_path() {
let expected = Path::new("../..");
let expanded = PathBuf::from(expand_path("..."));
assert_eq!(expected, &expanded);
}
#[test]
fn expand_in_absolute_path() {
let expected = Path::new("/foo/../..");
let expanded = PathBuf::from(expand_path("/foo/..."));
assert_eq!(expected, &expanded);
}
}