Optimized version of strip_current_dir

This commit is contained in:
sharkdp 2018-02-25 20:04:24 +01:00
parent 631931b431
commit a57a39ad63
2 changed files with 41 additions and 11 deletions

View File

@ -7,8 +7,8 @@
// according to those terms.
use std::env::current_dir;
use std::path::{Path, PathBuf};
use std::io;
use std::path::{Path, PathBuf};
pub fn path_absolute_form(path: &Path) -> io::Result<PathBuf> {
if path.is_absolute() {
@ -42,3 +42,42 @@ pub fn is_dir(path: &Path) -> bool {
path.is_dir() && path.canonicalize().is_ok()
}
}
/// Remove the `./` prefix from a path.
///
/// This code is an adapted version of the `pathutil::strip_prefix`
/// helper function in ripgrep (https://github.com/BurntSushi/ripgrep).
#[cfg(unix)]
pub fn strip_current_dir<'a>(path: &'a Path) -> &'a Path {
use std::os::unix::ffi::OsStrExt;
use std::ffi::OsStr;
let prefix = b"./";
let path_raw = path.as_os_str().as_bytes();
if path_raw.len() < 2 || &path_raw[0..2] != prefix {
path
} else {
Path::new(OsStr::from_bytes(&path_raw[2..]))
}
}
/// Remove the `./` prefix from a path.
#[cfg(not(unix))]
pub fn strip_current_dir<'a>(path: &'a Path) -> &'a Path {
path.strip_prefix("./").unwrap_or(&path)
}
#[test]
fn test_strip_current_dir() {
let expect_stripped = |expected, input| {
let stripped = Path::new(expected);
let base = Path::new(input);
assert_eq!(stripped, strip_current_dir(&base));
};
expect_stripped("foo/bar.txt", "./foo/bar.txt");
expect_stripped("", "./");
expect_stripped("foo", "./foo");
expect_stripped("foo.txt", "foo.txt");
expect_stripped("../foo", "../foo");
}

View File

@ -8,6 +8,7 @@
use internal::{FdOptions, EXITCODE_ERROR, EXITCODE_SIGINT};
use lscolors::LsColors;
use fshelper::strip_current_dir;
use std::{fs, process};
use std::io::{self, Write};
@ -20,16 +21,6 @@ use std::os::unix::fs::PermissionsExt;
use ansi_term;
/// Remove the `./` prefix from a path.
fn strip_current_dir<'a>(pathbuf: &'a PathBuf) -> &'a Path {
let mut iter = pathbuf.components();
let mut iter_next = iter.clone();
if iter_next.next() == Some(Component::CurDir) {
iter.next();
}
iter.as_path()
}
pub fn print_entry(entry: &PathBuf, config: &FdOptions, wants_to_quit: &Arc<AtomicBool>) {
let path = if entry.is_absolute() {
entry.as_path()