use std::path::Path;
use anyhow::Result;
use regex::Regex;
use crate::common::filename_from_path;
use crate::modes::Flagged;
pub fn regex_flagger(input_string: &str, paths: &[&Path], flagged: &mut Flagged) -> Result<()> {
let Ok(regex) = CaseDependantRegex::new(input_string) else {
return Ok(());
};
flagged.clear();
for path in paths {
if regex.is_match(filename_from_path(path)?) {
flagged.push(path.to_path_buf());
}
}
Ok(())
}
#[derive(Clone)]
pub struct CaseDependantRegex {
input_string: String,
regex: Regex,
}
impl CaseDependantRegex {
pub fn new(input_string: &str) -> Result<Self> {
Ok(Self {
input_string: input_string.to_string(),
regex: Self::complete_regex(input_string)?,
})
}
pub fn is_empty(&self) -> bool {
self.input_string.is_empty()
}
pub fn is_match(&self, haystack: &str) -> bool {
self.regex.is_match(haystack)
}
fn complete_regex(input_string: &str) -> Result<Regex> {
let re = if Self::has_uppercase(input_string) {
input_string
} else {
&format!("(?i){input_string}")
};
Ok(Regex::new(re)?)
}
fn has_uppercase(input_string: &str) -> bool {
input_string.chars().any(|c| c.is_uppercase())
}
}
impl std::fmt::Display for CaseDependantRegex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.input_string)
}
}