Skip to content

Commit

Permalink
The Rust side of cleanpath_conservative
Browse files Browse the repository at this point in the history
  • Loading branch information
danielpclark committed Feb 27, 2018
1 parent 6e0f241 commit 7146cfb
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 2 deletions.
110 changes: 110 additions & 0 deletions src/cleanpath_conservative.rs
@@ -0,0 +1,110 @@
use prepend_prefix::prepend_prefix;
use basename::basename;
use dirname::dirname;
use chop_basename::chop_basename;
extern crate array_tool;
use self::array_tool::vec::Shift;
use std::path::MAIN_SEPARATOR;

pub fn cleanpath_conservative(path: &str) -> String {
let sep = MAIN_SEPARATOR.to_string();
let mut names: Vec<String> = vec![];
let mut pre = path.to_string();
loop {
match chop_basename(&pre) {
Some((ref p, ref base)) => {
pre = p.to_string();
match base.as_ref() {
"." => {},
_ => names.unshift(base.to_string()),
}
},
None => break,
}
}
// // Windows Feature
//
// ```ruby
// pre.tr!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
// ```
//
if basename(&pre, "").contains(&sep) {
loop {
if names.first() == Some(&"..".to_string()) {
let _ = names.shift();
} else {
break
}
}
}

if names.is_empty() {
return dirname(&pre).to_string();
}

if names.last() != Some(&"..".to_string()) && basename(&path, "") == &".".to_string() {
names.push(".".to_string());
}

let result = prepend_prefix(&pre, &names.join(&sep)[..]);
let last = names.last();

if !(last == Some(&".".to_string()) || last == Some(&"..".to_string())) &&
chop_basename(path).map(|(a, b)| a.len() + b.len()).unwrap() < path.len() {
format!("{}{}", last.unwrap(), MAIN_SEPARATOR)
} else {
result
}
}

#[test]
fn it_conservatively_cleans_the_path() {
assert_eq!(cleanpath_conservative("/"), "/");
assert_eq!(cleanpath_conservative(""), ".");
assert_eq!(cleanpath_conservative("."), ".");
assert_eq!(cleanpath_conservative(".."), "..");
assert_eq!(cleanpath_conservative("a"), "a");
assert_eq!(cleanpath_conservative("/."), "/");
assert_eq!(cleanpath_conservative("/.."), "/");
assert_eq!(cleanpath_conservative("/a"), "/a");
assert_eq!(cleanpath_conservative("./"), ".");
assert_eq!(cleanpath_conservative("../"), "..");
assert_eq!(cleanpath_conservative("a/"), "a/");
assert_eq!(cleanpath_conservative("a//b"), "a/b");
assert_eq!(cleanpath_conservative("a/."), "a/.");
assert_eq!(cleanpath_conservative("a/./"), "a/.");
assert_eq!(cleanpath_conservative("a/../"), "a/..");
assert_eq!(cleanpath_conservative("/a/."), "/a/.");
assert_eq!(cleanpath_conservative("./.."), "..");
assert_eq!(cleanpath_conservative("../."), "..");
assert_eq!(cleanpath_conservative("./../"), "..");
assert_eq!(cleanpath_conservative(".././"), "..");
assert_eq!(cleanpath_conservative("/./.."), "/");
assert_eq!(cleanpath_conservative("/../."), "/");
assert_eq!(cleanpath_conservative("/./../"), "/");
assert_eq!(cleanpath_conservative("/.././"), "/");
assert_eq!(cleanpath_conservative("a/b/c"), "a/b/c");
assert_eq!(cleanpath_conservative("./b/c"), "b/c");
assert_eq!(cleanpath_conservative("a/./c"), "a/c");
assert_eq!(cleanpath_conservative("a/b/."), "a/b/.");
assert_eq!(cleanpath_conservative("a/../."), "a/..");
assert_eq!(cleanpath_conservative("/../.././../a"), "/a");
assert_eq!(cleanpath_conservative("a/b/../../../../c/../d"), "a/b/../../../../c/../d");
;
// Future Windows Support
//
// DOSISH = File::ALT_SEPARATOR != nil
// DOSISH_DRIVE_LETTER = File.dirname("A:") == "A:."
// DOSISH_UNC = File.dirname("//") == "//"
//
//
// if DOSISH
// assert_eq!(cleanpath_conservative, 'c:/foo/bar', 'c:\\foo\\bar')
// end
//
// if DOSISH_UNC
// assert_eq!(cleanpath_conservative, '//', '//')
// else
// assert_eq!(cleanpath_conservative, '/', '//')
// end
}
5 changes: 4 additions & 1 deletion src/lib.rs
Expand Up @@ -17,6 +17,7 @@ mod pathname;
mod basename;
mod chop_basename;
mod cleanpath_aggressive;
mod cleanpath_conservative;
mod dirname;
mod extname;
mod pathname_sys;
Expand Down Expand Up @@ -66,7 +67,9 @@ methods!(
pathname::pn_cleanpath_aggressive(pth)
}

// fn r_cleanpath_conservative(pth: RString){}
fn pub_cleanpath_conservative(pth: RString) -> RString {
pathname::pn_cleanpath_conservative(pth)
}

// fn r_del_trailing_separator(pth: RString){}

Expand Down
9 changes: 8 additions & 1 deletion src/pathname.rs
Expand Up @@ -2,6 +2,7 @@ use helpers::*;
use basename;
use chop_basename;
use cleanpath_aggressive;
use cleanpath_conservative;
use dirname;
use extname;
use plus;
Expand Down Expand Up @@ -129,7 +130,13 @@ pub fn pn_cleanpath_aggressive(pth: MaybeString) -> RString {
RString::new(&path)
}

// pub fn pn_cleanpath_conservative(pth: MaybeString){}
pub fn pn_cleanpath_conservative(pth: MaybeString) -> RString {
let path = cleanpath_conservative::cleanpath_conservative(
pth.ok().unwrap_or(RString::new("")).to_str()
);

RString::new(&path)
}

// pub fn pn_del_trailing_separator(pth: MaybeString){}

Expand Down

0 comments on commit 7146cfb

Please sign in to comment.