From 370d9f081fd4d22eb4c8c1ac04d647fd718688b1 Mon Sep 17 00:00:00 2001 From: Martin Larralde Date: Wed, 7 Feb 2018 16:13:28 +0100 Subject: [PATCH] Use RegexSet instead of hand-written parser --- src/internal.rs | 3 ++- src/main.rs | 14 ++++++++++---- src/utils.rs | 45 --------------------------------------------- src/walk.rs | 9 +++++---- 4 files changed, 17 insertions(+), 54 deletions(-) delete mode 100644 src/utils.rs 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>, + pub extensions: Option, /// If a value is supplied, each item found will be used to generate and execute commands. pub command: Option, 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 -// -// or the MIT license , -// 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 + 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, config: Arc) { } // 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; + } } }