From 1dfd1ae32b9b27573b9ee4439674091b792bcce0 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 16 Aug 2026 20:20:15 +0900 Subject: refactor(preg): make preg_grep() return an iterator Callers had to build a temporary Vec<&str> at every call site to satisfy the &[&str] parameter. Taking IntoIterator and yielding the matched items lets them pass owned or borrowed strings directly. The flags variant and PREG_GREP_INVERT go away with it: no caller passes flags, and Composer's Preg::grep() has no such parameter either. --- crates/shirabe-pcre/src/preg.rs | 13 ++++++------ crates/shirabe-php-shim/src/preg.rs | 23 ++++++++-------------- crates/shirabe-symfony-process/src/process.rs | 2 +- crates/shirabe/src/command/remove_command.rs | 21 ++++++++++---------- crates/shirabe/src/console/application.rs | 14 +++++++++---- .../shirabe/src/repository/composer_repository.rs | 11 +++-------- 6 files changed, 38 insertions(+), 46 deletions(-) (limited to 'crates') diff --git a/crates/shirabe-pcre/src/preg.rs b/crates/shirabe-pcre/src/preg.rs index 0ebc0ff2..e197c874 100644 --- a/crates/shirabe-pcre/src/preg.rs +++ b/crates/shirabe-pcre/src/preg.rs @@ -15,7 +15,7 @@ use indexmap::IndexMap; pub use shirabe_php_shim::CaptureKey; use shirabe_php_shim::{ PREG_OFFSET_CAPTURE, PREG_SET_ORDER, PREG_SPLIT_OFFSET_CAPTURE, PREG_UNMATCHED_AS_NULL, - PregPattern, preg_grep2, preg_match_all_offset_capture2, preg_match_all2, preg_match2, + PregPattern, preg_grep, preg_match_all_offset_capture2, preg_match_all2, preg_match2, preg_replace_callback, preg_replace2, preg_split2, }; @@ -180,12 +180,11 @@ impl Preg { preg_split2(pattern, subject, limit, flags) } - pub fn grep(pattern: impl PregPattern, array: &[&str]) -> Vec { - Self::grep3(pattern, array, 0) - } - - pub fn grep3(pattern: impl PregPattern, array: &[&str], flags: i64) -> Vec { - preg_grep2(pattern, array, flags) + pub fn grep>( + pattern: impl PregPattern, + array: impl IntoIterator, + ) -> impl Iterator { + preg_grep(pattern, array) } pub fn is_match(pattern: impl PregPattern, subject: &str) -> bool { diff --git a/crates/shirabe-php-shim/src/preg.rs b/crates/shirabe-php-shim/src/preg.rs index 637e969d..727fc149 100644 --- a/crates/shirabe-php-shim/src/preg.rs +++ b/crates/shirabe-php-shim/src/preg.rs @@ -8,7 +8,6 @@ pub const PREG_UNMATCHED_AS_NULL: i64 = 512; pub const PREG_SPLIT_NO_EMPTY: i64 = 1; pub const PREG_SPLIT_DELIM_CAPTURE: i64 = 2; pub const PREG_SPLIT_OFFSET_CAPTURE: i64 = 4; -pub const PREG_GREP_INVERT: i64 = 1; #[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum CaptureKey { @@ -242,21 +241,15 @@ pub fn preg_match_all_offset_capture2( count } -pub fn preg_grep(pattern: impl PregPattern, input: &[String]) -> Vec { - let __resolved = pattern.resolve(); - let (re, _anchored) = __resolved.parts(); - input.iter().filter(|s| re.is_match(s)).cloned().collect() -} - -pub fn preg_grep2(pattern: impl PregPattern, array: &[&str], flags: i64) -> Vec { +pub fn preg_grep>( + pattern: impl PregPattern, + array: impl IntoIterator, +) -> impl Iterator { let __resolved = pattern.resolve(); - let (re, _anchored) = __resolved.parts(); - let invert = flags & PREG_GREP_INVERT != 0; - array - .iter() - .filter(|s| re.is_match(s) != invert) - .map(|s| s.to_string()) - .collect() + array.into_iter().filter(move |s| { + let (re, _anchored) = __resolved.parts(); + re.is_match(s.as_ref()) + }) } pub fn preg_split(pattern: impl PregPattern, subject: &str) -> Vec { diff --git a/crates/shirabe-symfony-process/src/process.rs b/crates/shirabe-symfony-process/src/process.rs index 5307e1ae..045224c5 100644 --- a/crates/shirabe-symfony-process/src/process.rs +++ b/crates/shirabe-symfony-process/src/process.rs @@ -988,7 +988,7 @@ impl Process { .map(|spec| { format!( "\"{}\"", - preg_replace(php_regex!(r#"{(\\*+)"}"#), "$1$1\\\"", &spec,) + preg_replace(php_regex!(r#"{(\\*+)"}"#), "$1$1\\\"", &spec) ) }) }) diff --git a/crates/shirabe/src/command/remove_command.rs b/crates/shirabe/src/command/remove_command.rs index a8b525e6..bba0285f 100644 --- a/crates/shirabe/src/command/remove_command.rs +++ b/crates/shirabe/src/command/remove_command.rs @@ -393,11 +393,11 @@ impl Command for RemoveCommand { .and_then(|v| v.as_array()) .map(|m| m.keys().cloned().collect()) .unwrap_or_default(); - let type_keys_refs: Vec<&str> = type_keys.iter().map(|s| s.as_str()).collect(); - let matches_in_type = Preg::grep( + let matches_in_type: Vec<&String> = Preg::grep( base_package::package_name_to_regexp(package), - &type_keys_refs, - ); + type_keys.iter(), + ) + .collect(); let alt_type_keys: Vec = composer_data .as_array() @@ -405,15 +405,14 @@ impl Command for RemoveCommand { .and_then(|v| v.as_array()) .map(|m| m.keys().cloned().collect()) .unwrap_or_default(); - let alt_type_keys_refs: Vec<&str> = - alt_type_keys.iter().map(|s| s.as_str()).collect(); - let matches_in_alt_type = Preg::grep( + let matches_in_alt_type: Vec<&String> = Preg::grep( base_package::package_name_to_regexp(package), - &alt_type_keys_refs, - ); + alt_type_keys.iter(), + ) + .collect(); if !type_keys.is_empty() && !matches_in_type.is_empty() { - for matched_package in &matches_in_type { + for matched_package in matches_in_type { if dry_run { to_remove .entry(r#type.to_string()) @@ -424,7 +423,7 @@ impl Command for RemoveCommand { } } } else if !alt_type_keys.is_empty() && !matches_in_alt_type.is_empty() { - for matched_package in &matches_in_alt_type { + for matched_package in matches_in_alt_type { io.write_error(&format!( "{} could not be found in {} but it is present in {}", matched_package, r#type, alt_type diff --git a/crates/shirabe/src/console/application.rs b/crates/shirabe/src/console/application.rs index 9033700b..b55b9e68 100644 --- a/crates/shirabe/src/console/application.rs +++ b/crates/shirabe/src/console/application.rs @@ -953,7 +953,8 @@ impl Application { .map(|p| preg_quote(&p, None)) .collect(); let expr = format!("{}{}", shirabe_php_shim::implode("[^:]*:", &parts), "[^:]*"); - let namespaces = preg_grep(format!("{{^{}}}", expr), &all_namespaces); + let namespaces: Vec = + preg_grep(format!("{{^{}}}", expr), all_namespaces.iter().cloned()).collect(); if namespaces.is_empty() { let mut message = format!( @@ -1049,14 +1050,19 @@ impl Application { .map(|p| preg_quote(&p, None)) .collect(); let expr = format!("{}{}", shirabe_php_shim::implode("[^:]*:", &parts), "[^:]*"); - let mut commands = preg_grep(format!("{{^{}}}", expr), &all_commands); + let mut commands: Vec = + preg_grep(format!("{{^{}}}", expr), all_commands.iter().cloned()).collect(); if commands.is_empty() { - commands = preg_grep(format!("{{^{}}}i", expr), &all_commands); + commands = preg_grep(format!("{{^{}}}i", expr), all_commands.iter().cloned()).collect(); } // if no commands matched or we just matched namespaces - if commands.is_empty() || preg_grep(format!("{{^{}$}}i", expr), &commands).is_empty() { + if commands.is_empty() + || preg_grep(format!("{{^{}$}}i", expr), commands.iter()) + .next() + .is_none() + { if let Some(pos) = shirabe_php_shim::strrpos(name, ":") { // check if a namespace exists and contains commands self.find_namespace(&name[..pos])?; diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs index 2faf33dc..ab8572ad 100644 --- a/crates/shirabe/src/repository/composer_repository.rs +++ b/crates/shirabe/src/repository/composer_repository.rs @@ -430,10 +430,7 @@ impl ComposerRepository { }; let filter_results = |results: Vec| -> anyhow::Result> { match &package_filter_regex { - Some(regex) => { - let results_refs: Vec<&str> = results.iter().map(|s| s.as_str()).collect(); - Ok(Preg::grep(regex, &results_refs)) - } + Some(regex) => Ok(Preg::grep(regex, results).collect()), None => Ok(results), } }; @@ -771,8 +768,7 @@ impl ComposerRepository { let regex = format!("{{(?:{})}}i", parts.join("|")); let vendor_names = self.get_vendor_names()?; - let vendor_names_refs: Vec<&str> = vendor_names.iter().map(|s| s.as_str()).collect(); - for name in Preg::grep(®ex, &vendor_names_refs) { + for name in Preg::grep(®ex, vendor_names) { let mut entry = IndexMap::new(); entry.insert("name".to_string(), PhpMixed::String(name)); entry.insert("description".to_string(), PhpMixed::String(String::new())); @@ -836,8 +832,7 @@ impl ComposerRepository { let regex = format!("{{(?:{})}}i", parts.join("|")); let package_names = self.get_package_names(None)?; - let package_names_refs: Vec<&str> = package_names.iter().map(|s| s.as_str()).collect(); - for name in Preg::grep(®ex, &package_names_refs) { + for name in Preg::grep(®ex, package_names) { let mut entry = IndexMap::new(); entry.insert("name".to_string(), PhpMixed::String(name)); entry.insert("description".to_string(), PhpMixed::String(String::new())); -- cgit v1.3.1-4-g156e