Skip to content

Commit

Permalink
Correctly handle regex errors when using advanced regex for path
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasschafer committed Dec 7, 2024
1 parent 4825f54 commit 0d0e9e6
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 16 deletions.
43 changes: 30 additions & 13 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Error;
use fancy_regex::Regex as FancyRegex;
use ignore::WalkState;
use itertools::Itertools;
Expand Down Expand Up @@ -321,6 +322,22 @@ impl SearchFields {
};
Ok(result)
}

pub fn path_pattern_parsed(&self) -> anyhow::Result<Option<SearchType>> {
let path_patt_text = &self.path_pattern().text;
let result = if path_patt_text.is_empty() {
None
} else {
Some({
if self.advanced_regex {
SearchType::PatternAdvanced(FancyRegex::new(path_patt_text)?)
} else {
SearchType::Pattern(Regex::new(path_patt_text)?)
}
})
};
Ok(result)
}
}

enum ValidatedField<T> {
Expand Down Expand Up @@ -627,13 +644,18 @@ impl App {
})
}

fn is_regex_error(e: &Error) -> bool {
e.downcast_ref::<regex::Error>().is_some()
|| e.downcast_ref::<fancy_regex::Error>().is_some()
}

fn validate_fields(
&mut self,
background_processing_sender: UnboundedSender<BackgroundProcessingEvent>,
) -> anyhow::Result<Option<ParsedFields>> {
let search_pattern = match self.search_fields.search_type() {
Err(e) => {
if e.downcast_ref::<regex::Error>().is_some() {
if Self::is_regex_error(&e) {
self.search_fields
.search_mut()
.set_error("Couldn't parse regex".to_owned(), e.to_string());
Expand All @@ -645,19 +667,14 @@ impl App {
Ok(p) => ValidatedField::Parsed(p),
};

let path_pattern_text = self.search_fields.path_pattern().text();
let path_pattern = if path_pattern_text.is_empty() {
ValidatedField::Parsed(None)
} else {
match Regex::new(path_pattern_text.as_str()) {
Err(e) => {
self.search_fields
.path_pattern_mut()
.set_error("Couldn't parse regex".to_owned(), e.to_string());
ValidatedField::Error
}
Ok(r) => ValidatedField::Parsed(Some(r)),
let path_pattern = match self.search_fields.path_pattern_parsed() {
Err(e) => {
self.search_fields
.path_pattern_mut()
.set_error("Couldn't parse regex".to_owned(), e.to_string());
ValidatedField::Error
}
Ok(r) => ValidatedField::Parsed(r),
};

let (search_pattern, path_pattern) = match (search_pattern, path_pattern) {
Expand Down
13 changes: 10 additions & 3 deletions src/parsed_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub enum SearchType {
pub struct ParsedFields {
search_pattern: SearchType,
replace_string: String,
path_pattern: Option<Regex>,
path_pattern: Option<SearchType>,
// TODO: `root_dir` and `include_hidden` are duplicated across this and App
root_dir: PathBuf,
include_hidden: bool,
Expand All @@ -38,7 +38,7 @@ impl ParsedFields {
pub fn new(
search_pattern: SearchType,
replace_string: String,
path_pattern: Option<Regex>,
path_pattern: Option<SearchType>,
root_dir: PathBuf,
include_hidden: bool,
background_processing_sender: UnboundedSender<BackgroundProcessingEvent>,
Expand All @@ -55,7 +55,14 @@ impl ParsedFields {

pub fn handle_path(&self, path: &Path) {
if let Some(ref p) = self.path_pattern {
let matches_pattern = p.is_match(relative_path_from(&self.root_dir, path).as_str());
let relative_path = relative_path_from(&self.root_dir, path);
let relative_path = relative_path.as_str();

let matches_pattern = match p {
SearchType::Pattern(ref p) => p.is_match(relative_path),
SearchType::PatternAdvanced(ref p) => p.is_match(relative_path).unwrap(),
SearchType::Fixed(ref s) => relative_path.contains(s),
};
if !matches_pattern {
return;
}
Expand Down

0 comments on commit 0d0e9e6

Please sign in to comment.