diff options
author | Martin Larralde <martin.larralde@ens-cachan.fr> | 2018-02-07 16:13:28 +0100 |
---|---|---|
committer | David Peter <sharkdp@users.noreply.github.com> | 2018-02-10 14:18:37 +0100 |
commit | 370d9f081fd4d22eb4c8c1ac04d647fd718688b1 (patch) | |
tree | e1e1d36067801361cb02d21f6ec514bcf97416ad | |
parent | 86fe9977e8953ba3da826f233e6a51c561a78724 (diff) |
Use RegexSet instead of hand-written parser
-rw-r--r-- | src/internal.rs | 3 | ||||
-rw-r--r-- | src/main.rs | 14 | ||||
-rw-r--r-- | src/utils.rs | 45 | ||||
-rw-r--r-- | src/walk.rs | 9 |
4 files changed, 17 insertions, 54 deletions
diff --git a/src/internal.rs b/src/internal.rs index c903204..fe9a43d 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -16,6 +16,7 @@ use exec::CommandTemplate; use lscolors::LsColors; use walk::FileType; use regex_syntax::{Expr, ExprBuilder}; +use regex::RegexSet; /// Configuration options for *fd*. pub struct FdOptions { @@ -65,7 +66,7 @@ pub struct FdOptions { /// The extension to search for. Only entries matching the extension will be included. /// /// The value (if present) will be a lowercase string without leading dots. - pub extensions: Option<HashSet<String>>, + pub extensions: Option<RegexSet>, /// If a value is supplied, each item found will be used to generate and execute commands. pub command: Option<CommandTemplate>, diff --git a/src/main.rs b/src/main.rs index 62f5d41..bd714f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,6 @@ mod app; mod exec; mod internal; mod output; -mod utils; mod walk; #[cfg(windows)] @@ -38,7 +37,7 @@ use std::sync::Arc; use std::time; use atty::Stream; -use regex::RegexBuilder; +use regex::{RegexBuilder, RegexSetBuilder}; use exec::CommandTemplate; use internal::{error, pattern_has_uppercase_char, transform_args_with_exec, FdOptions}; @@ -153,8 +152,15 @@ fn main() { .collect(), }, extensions: matches.values_of("extension").map(|exts| { - exts.map(|e| String::from(".") + &e.trim_left_matches('.')) - .collect() + let patterns = exts.map(|e| e.trim_left_matches('.')) + .map(|e| format!(r".\.{}$", regex::escape(e))); + match RegexSetBuilder::new(patterns) + .case_insensitive(true) + .build() + { + Ok(re) => re, + Err(err) => error(err.description()), + } }), command, exclude_patterns: matches diff --git a/src/utils.rs b/src/utils.rs deleted file mode 100644 index f2c3926..0000000 --- a/src/utils.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2017 fd developers -// Licensed under the Apache License, Version 2.0 -// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> -// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>, -// at your option. All files in the project carrying such -// notice may not be copied, modified, or distributed except -// according to those terms. - -use std::path::Path; -use std::iter::Iterator; - -/// Determine if an os string ends with any of the given extensions (case insensitive). -pub fn path_has_any_extension<'a, I>(path: &Path, exts: I) -> bool -where - I: 'a + Iterator<Item = &'a String> + Clone, -{ - // TODO: remove these two lines when we drop support for Rust version < 1.23. - #[allow(unused_imports)] - use std::ascii::AsciiExt; - - if let Some(ref name) = path.file_name() { - if let Some(ref name_str) = name.to_str() { - exts.clone().any(|x| { - let mut it = name_str.chars().rev(); - - if x.chars() - .rev() - .zip(&mut it) - .all(|(a, b)| a.eq_ignore_ascii_case(&b)) - { - match it.next() { - Some('/') | None => false, - _ => true, - } - } else { - false - } - }) - } else { - false - } - } else { - false - } -} diff --git a/src/walk.rs b/src/walk.rs index 121d3a8..ac71fa9 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -11,7 +11,6 @@ extern crate ctrlc; use exec; use fshelper; use internal::{error, FdOptions, EXITCODE_SIGINT, MAX_BUFFER_LENGTH}; -use utils::path_has_any_extension; use output; use std::process; @@ -214,9 +213,11 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc<Regex>, config: Arc<FdOptions>) { } // Filter out unwanted extensions. - if let Some(ref filter_exts) = config.extensions { - if !path_has_any_extension(entry_path, filter_exts.iter()) { - return ignore::WalkState::Continue; + if let Some(ref exts_regex) = config.extensions { + if let Some(path_str) = entry_path.file_name().map_or(None, |s| s.to_str()) { + if !exts_regex.is_match(path_str) { + return ignore::WalkState::Continue; + } } } |