Skip to content

Commit 0257714

Browse files
authored
Merge pull request #158 from glebm/chop-basename
Improve chop_basename performance (72.9% -> 75.6%)
2 parents af61c28 + 061c088 commit 0257714

File tree

1 file changed

+12
-13
lines changed

1 file changed

+12
-13
lines changed

src/chop_basename.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
1-
use std::path::MAIN_SEPARATOR;
1+
use path_parsing::{find_last_non_sep_pos, find_last_sep_pos};
22
use std::str;
33

44
pub fn chop_basename<'a>(input: &'a str) -> Option<(&'a str, &'a str)> {
5-
if input.is_empty() {
5+
let bytes = input.as_bytes();
6+
let len = find_last_non_sep_pos(&bytes)? + 1;
7+
let base_start = find_last_sep_pos(&bytes[..len]).map_or(0, |pos| pos + 1);
8+
if base_start == len {
69
return None;
710
}
8-
9-
let input = input.trim_right_matches(MAIN_SEPARATOR);
10-
let end = input.rsplitn(2, MAIN_SEPARATOR).nth(0).unwrap().len();
11-
let base = &input[input.len()-end..input.len()];
12-
let directory = &input[0..input.len()-base.len()];
13-
14-
if directory.is_empty() && (base.is_empty() || base.chars().next().unwrap() == MAIN_SEPARATOR) {
15-
return None
16-
};
17-
18-
Some((directory, base))
11+
Some((&input[0..base_start], &input[base_start..len]))
1912
}
2013

2114
#[test]
@@ -27,5 +20,11 @@ fn it_chops_the_basename_and_dirname() {
2720
assert_eq!(chop_basename("asdf.txt"), Some(("", "asdf.txt")) );
2821
assert_eq!(chop_basename("asdf/"), Some(("", "asdf")) );
2922
assert_eq!(chop_basename("/asdf/"), Some(("/", "asdf")) );
23+
assert_eq!(chop_basename("a///b"), Some(("a///", "b")) );
24+
assert_eq!(chop_basename("a///b//"), Some(("a///", "b")) );
25+
assert_eq!(chop_basename("/a///b//"), Some(("/a///", "b")) );
26+
assert_eq!(chop_basename("/a///b//"), Some(("/a///", "b")) );
27+
28+
assert_eq!(chop_basename("./../..///.../..//"), Some(("./../..///.../", "..")));
3029
}
3130

0 commit comments

Comments
 (0)