#![feature(test)]
extern crate libc;
extern crate test;
use std::path::MAIN_SEPARATOR;
static SEP: u8 = MAIN_SEPARATOR as u8;
pub fn extract_last_path_segment_str(path: &str) -> &str {
path.trim_right_matches(MAIN_SEPARATOR).rsplit(MAIN_SEPARATOR).next().unwrap_or("")
}
pub fn extract_last_path_segment_bytes(mut path: &str) -> &str {
path = match path.bytes().rposition(|b| b != SEP) {
Some(pos) => &path[..pos + 1],
_ => &path[..0]
};
if let Some(pos) = path.bytes().rposition(|b| b == SEP) {
path = &path[pos + 1..];
}
path
}
pub fn extract_last_path_segment_pointer(path: &str) -> &str {
let ptr = path.as_ptr();
let mut i = path.len() as isize - 1;
while i >= 0 {
let c = unsafe { *ptr.offset(i) };
if c != SEP { break; };
i -= 1;
}
let end = (i + 1) as usize;
while i >= 0 {
let c = unsafe { *ptr.offset(i) };
if c == SEP {
return &path[(i + 1) as usize..end];
};
i -= 1;
}
&path[..end]
}
#[cfg(test)]
mod tests {
use super::*;
use test::Bencher;
use test::black_box;
static PATH_FOR_BENCH: &'static str = "/hellooooooooo/woλλλλrλd/";
#[bench]
fn bench_extract_last_path_segment_bytes(b: &mut Bencher) {
let path = black_box(PATH_FOR_BENCH);
b.iter(|| extract_last_path_segment_bytes(path));
}
#[bench]
fn bench_extract_last_path_segment_str(b: &mut Bencher) {
let path = black_box(PATH_FOR_BENCH);
b.iter(|| extract_last_path_segment_str(path));
}
#[bench]
fn bench_extract_last_path_segment_pointer(b: &mut Bencher) {
let path = black_box(PATH_FOR_BENCH);
b.iter(|| extract_last_path_segment_pointer(path));
}
}