@ 261104.1

261028.3.1 · 23815624819c77ab665e19c8e6c28bddbcd96e1d

refactor: different pattern types

This significantly refactors the code for creating the regexes to match with, and in some cases avoids using regex altogether.

We now have differnt types of patterns that we match with.

One impact of this is that we now use GlobSet to match directly, which should fix #2067 and allow globs to work correctly in windows with --full-path.

reading declarations

Changes to src/walk.rs. All files

src/walk.rs

@@ -13,14 +13,13 @@ use crossbeam_channel::{Receiver, RecvTimeoutError, SendError, Sender, bounded}; use etcetera::BaseStrategy; use ignore::overrides::{Override, OverrideBuilder}; use ignore::{WalkBuilder, WalkParallel, WalkState};-use regex::bytes::Regex;  use crate::config::Config; use crate::dir_entry::DirEntry; use crate::exec; use crate::exit_codes::{ExitCode, merge_exitcodes};-use crate::filesystem; use crate::output;+use crate::patterns::Patterns;  /// The receiver thread can either be buffering results or directly streaming to the console. #[derive(PartialEq)]@@ -304,7 +303,7 @@ impl<'a, W: Write> ReceiverBuffer<'a, W> { /// State shared by the sender and receiver threads. struct WorkerState {     /// The search patterns.-    patterns: Vec<Regex>,+    patterns: Patterns,     /// The command line configuration.     config: Config,     /// Flag for cleanly shutting down the parallel walk@@ -314,7 +313,7 @@ struct WorkerState { }  impl WorkerState {-    fn new(patterns: Vec<Regex>, config: Config) -> Self {+    fn new(patterns: Patterns, config: Config) -> Self {         let quit_flag = Arc::new(AtomicBool::new(false));         let interrupt_flag = Arc::new(AtomicBool::new(false)); @@ -505,17 +504,14 @@ impl WorkerState {                  let search_str = search_str_for_entry(entry_path, config.full_path_base.as_deref()); -                if !patterns-                    .iter()-                    .all(|pat| pat.is_match(&filesystem::osstr_to_bytes(search_str.as_ref())))-                {+                if !patterns.matches_path(&search_str) {                     return WalkState::Continue;                 }                  // Filter out unwanted extensions.                 if let Some(ref exts_regex) = config.extensions {                     if let Some(path_str) = entry_path.file_name() {-                        if !exts_regex.is_match(&filesystem::osstr_to_bytes(path_str)) {+                        if !exts_regex.is_match(path_str.as_encoded_bytes()) {                             return WalkState::Continue;                         }                     } else {@@ -714,7 +710,7 @@ fn search_str_for_entry<'a>( /// If the `--exec` argument was supplied, this will create a thread pool for executing /// jobs in parallel from a given command line and the discovered paths. Otherwise, each /// path will simply be written to standard output.-pub fn scan(paths: &[PathBuf], patterns: Vec<Regex>, config: Config) -> Result<ExitCode> {+pub fn scan(paths: &[PathBuf], patterns: Patterns, config: Config) -> Result<ExitCode> {     WorkerState::new(patterns, config).scan(paths) }