diff options
author | sharkdp <davidpeter@web.de> | 2018-02-25 11:11:14 +0100 |
---|---|---|
committer | David Peter <sharkdp@users.noreply.github.com> | 2018-02-25 18:17:11 +0100 |
commit | 40d811c7be96914ed15c0e91df4ab4457a61a01d (patch) | |
tree | 07a54f3d4486fe408272af9047a02b58f038aa9c | |
parent | e5ee5eb7b360d3e15efd582d0ab5e11b880046e1 (diff) |
Rewrite of file-type filtering leading to 5% speed-up
-rw-r--r-- | src/internal.rs | 24 | ||||
-rw-r--r-- | src/main.rs | 31 | ||||
-rw-r--r-- | src/walk.rs | 27 |
3 files changed, 44 insertions, 38 deletions
diff --git a/src/internal.rs b/src/internal.rs index 172e32b..5d694b5 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -6,7 +6,6 @@ // notice may not be copied, modified, or distributed except // according to those terms. -use std::collections::HashSet; use std::ffi::OsString; use std::process; use std::time; @@ -14,10 +13,26 @@ use std::io::Write; use exec::CommandTemplate; use lscolors::LsColors; -use walk::FileType; use regex_syntax::{Expr, ExprBuilder}; use regex::RegexSet; +/// Whether or not to show +pub struct FileTypes { + pub files: bool, + pub directories: bool, + pub symlinks: bool, +} + +impl Default for FileTypes { + fn default() -> FileTypes { + FileTypes { + files: false, + directories: false, + symlinks: false, + } + } +} + /// Configuration options for *fd*. pub struct FdOptions { /// Whether the search is case-sensitive or case-insensitive. @@ -60,8 +75,9 @@ pub struct FdOptions { /// how to style different filetypes. pub ls_colors: Option<LsColors>, - /// The type of file to search for. All files other than the specified type will be ignored. - pub file_types: HashSet<FileType>, + /// The type of file to search for. If set to `None`, all file types are displayed. If + /// set to `Some(..)`, only the types that are specified are shown. + pub file_types: Option<FileTypes>, /// The extension to search for. Only entries matching the extension will be included. /// diff --git a/src/main.rs b/src/main.rs index e40e730..df749db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,9 +40,8 @@ use atty::Stream; use regex::{RegexBuilder, RegexSetBuilder}; use exec::CommandTemplate; -use internal::{error, pattern_has_uppercase_char, transform_args_with_exec, FdOptions}; +use internal::{error, pattern_has_uppercase_char, transform_args_with_exec, FdOptions, FileTypes}; use lscolors::LsColors; -use walk::FileType; fn main() { let checked_args = transform_args_with_exec(env::args_os()); @@ -142,22 +141,18 @@ fn main() { .and_then(|n| u64::from_str_radix(n, 10).ok()) .map(time::Duration::from_millis), ls_colors, - file_types: match matches.values_of("file-type") { - None => vec![ - FileType::RegularFile, - FileType::Directory, - FileType::SymLink, - ].into_iter() - .collect(), - Some(values) => values - .map(|value| match value { - "f" | "file" => FileType::RegularFile, - "d" | "directory" => FileType::Directory, - "l" | "symlink" => FileType::SymLink, - _ => FileType::RegularFile, - }) - .collect(), - }, + file_types: matches.values_of("file-type").map(|values| { + let mut file_types = FileTypes::default(); + for value in values { + match value { + "f" | "file" => file_types.files = true, + "d" | "directory" => file_types.directories = true, + "l" | "symlink" => file_types.symlinks = true, + _ => unreachable!(), + } + } + file_types + }), extensions: matches.values_of("extension").map(|exts| { let patterns = exts.map(|e| e.trim_left_matches('.')) .map(|e| format!(r".\.{}$", regex::escape(e))); diff --git a/src/walk.rs b/src/walk.rs index a1d32e2..346ab63 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -35,14 +35,6 @@ enum ReceiverMode { Streaming, } -/// The types of file to search for. -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub enum FileType { - RegularFile, - Directory, - SymLink, -} - /// Recursively scan the given search path for files / pathnames matching the pattern. /// /// If the `--exec` argument was supplied, this will create a thread pool for executing @@ -206,14 +198,17 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc<Regex>, config: Arc<FdOptions>) { } // Filter out unwanted file types. - if (entry.file_type().map_or(false, |ft| ft.is_file()) - && !config.file_types.contains(&FileType::RegularFile)) - || (entry.file_type().map_or(false, |ft| ft.is_dir()) - && !config.file_types.contains(&FileType::Directory)) - || (entry.file_type().map_or(false, |ft| ft.is_symlink()) - && !config.file_types.contains(&FileType::SymLink)) - { - return ignore::WalkState::Continue; + if let Some(ref file_types) = config.file_types { + if let Some(ref entry_type) = entry.file_type() { + if (entry_type.is_file() && !file_types.files) + || (entry_type.is_dir() && !file_types.directories) + || (entry_type.is_symlink() && !file_types.symlinks) + { + return ignore::WalkState::Continue; + } + } else { + return ignore::WalkState::Continue; + } } // Filter out unwanted extensions. |