summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsharkdp <davidpeter@web.de>2018-02-25 20:04:24 +0100
committersharkdp <davidpeter@web.de>2018-02-25 20:16:30 +0100
commita57a39ad638f2eaab7c9e1ce50a12b08085fd78a (patch)
tree115ca05b9dcde3c4421eac7c83f9d4bfc3f3542b
parent631931b431aa9922c476b5c0931b91ad8661b421 (diff)
Optimized version of strip_current_diroptimized-strip_current_dir
-rw-r--r--src/fshelper/mod.rs41
-rw-r--r--src/output.rs11
2 files changed, 41 insertions, 11 deletions
diff --git a/src/fshelper/mod.rs b/src/fshelper/mod.rs
index b473a76..28a73a0 100644
--- a/src/fshelper/mod.rs
+++ b/src/fshelper/mod.rs
@@ -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");
+}
diff --git a/src/output.rs b/src/output.rs
index 115b31a..fc2aedd 100644
--- a/src/output.rs
+++ b/src/output.rs
@@ -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()