src/dirname.rs in faster_path-0.3.7 vs src/dirname.rs in faster_path-0.3.8

- old
+ new

@@ -1,26 +1,66 @@ -extern crate memchr; -use self::memchr::memrchr; -use path_parsing::{SEP, SEP_STR, last_non_sep_i, last_non_sep_i_before}; +use std::str; +use path_parsing::{find_last_sep_pos, find_last_non_sep_pos}; pub fn dirname(path: &str) -> &str { - if path.is_empty() { return "."; } - let non_sep_i = last_non_sep_i(path); - if non_sep_i == -1 { return *SEP_STR; } - return match memrchr(SEP, &path.as_bytes()[..non_sep_i as usize]) { - None => ".", - Some(0) => *SEP_STR, - Some(sep_i) => { - let non_sep_i2 = last_non_sep_i_before(path, sep_i as isize); - if non_sep_i2 != -1 { - &path[..(non_sep_i2 + 1) as usize] - } else { - *SEP_STR - } - } + let bytes = path.as_bytes(); + let mut last_slash_pos = match find_last_sep_pos(bytes) { + Some(pos) => pos, + _ => return ".", + }; + // Skip trailing slashes. + if last_slash_pos == bytes.len() - 1 { + let last_non_slash_pos = match find_last_non_sep_pos(&bytes[..last_slash_pos]) { + Some(pos) => pos, + _ => return "/" + }; + last_slash_pos = match find_last_sep_pos(&bytes[..last_non_slash_pos]) { + Some(pos) => pos, + _ => return "." + }; + }; + if let Some(end) = find_last_non_sep_pos(&bytes[..last_slash_pos]) { + &path[..end + 1] + } else { + "/" } } #[test] -fn returns_dot_for_empty_string(){ - assert_eq!(dirname(""), ".".to_string()); +fn absolute() { + assert_eq!(dirname("/a/b///c"), "/a/b"); +} + +#[test] +fn trailing_slashes_absolute() { + assert_eq!(dirname("/a/b///c//////"), "/a/b"); +} + +#[test] +fn relative() { + assert_eq!(dirname("b///c"), "b"); +} + +#[test] +fn trailing_slashes_relative() { + assert_eq!(dirname("b/c//"), "b"); +} + +#[test] +fn root() { + assert_eq!(dirname("//c"), "/"); +} + +#[test] +fn trailing_slashes_root() { + assert_eq!(dirname("//c//"), "/"); +} + +#[test] +fn trailing_slashes_relative_root() { + assert_eq!(dirname("c//"), "."); +} + +#[test] +fn returns_dot_for_empty_string() { + assert_eq!(dirname(""), "."); }