diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-17 07:36:34 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-17 07:36:34 +0900 |
| commit | 9fd6aecad27240ccedab4487f6c157914142ca47 (patch) | |
| tree | 3819360771b9eb9298315e26604cafabeae84e04 /crates/shirabe-symfony-console | |
| parent | 6b4ce98f20b3cfc14f1c955565a8acd9abcc16a2 (diff) | |
| download | php-shirabe-9fd6aecad27240ccedab4487f6c157914142ca47.tar.gz php-shirabe-9fd6aecad27240ccedab4487f6c157914142ca47.tar.zst php-shirabe-9fd6aecad27240ccedab4487f6c157914142ca47.zip | |
refactor(preg): return the preg_* $matches instead of filling an out-param
PHP fills `$matches` through a by-ref parameter, which the port mirrored
with a `&mut` out-param plus a bool or count return. Every caller then
had to declare an empty binding one line ahead of the call, and nothing
in the type said the binding is only meaningful when the call succeeded.
Return the matches instead: preg_match() and preg_match2() hand back an
Option, and the three preg_match_all* functions hand back the collection
they used to fill.
The occurrence count the two map-shaped preg_match_all* functions used
to return is the length of any one of the map's columns, so it is not
lost -- Preg::match_all() and friends derive it via occurrence_count().
preg_replace2() keeps its `count: Option<&mut usize>`: that one is not
derivable from the replaced string, and callers that do not want it pay
nothing for passing None.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-symfony-console')
10 files changed, 31 insertions, 57 deletions
diff --git a/crates/shirabe-symfony-console/src/command/command.rs b/crates/shirabe-symfony-console/src/command/command.rs index b2af47e2..848cece3 100644 --- a/crates/shirabe-symfony-console/src/command/command.rs +++ b/crates/shirabe-symfony-console/src/command/command.rs @@ -108,8 +108,7 @@ impl CommandData { /// /// Throws InvalidArgumentException when the name is invalid. fn validate_name(&self, name: &str) -> anyhow::Result<Result<(), InvalidArgumentException>> { - let mut matches: Vec<Option<String>> = Vec::new(); - if !preg_match(php_regex!(r"/^[^\:]++(\:[^\:]++)*$/"), name, &mut matches) { + if preg_match(php_regex!(r"/^[^\:]++(\:[^\:]++)*$/"), name).is_none() { return Ok(Err(InvalidArgumentException::new(format!( "Command name \"{}\" is invalid.", name diff --git a/crates/shirabe-symfony-console/src/formatter/output_formatter.rs b/crates/shirabe-symfony-console/src/formatter/output_formatter.rs index c7c06cf5..1153bc9e 100644 --- a/crates/shirabe-symfony-console/src/formatter/output_formatter.rs +++ b/crates/shirabe-symfony-console/src/formatter/output_formatter.rs @@ -7,8 +7,8 @@ use crate::formatter::output_formatter_style_interface::OutputFormatterStyleInte use crate::formatter::output_formatter_style_stack::OutputFormatterStyleStack; use crate::formatter::wrappable_output_formatter_interface::WrappableOutputFormatterInterface; use shirabe_php_shim::{ - CaptureKey, PregMatchesAllWithOffsets, php_regex, preg_match, preg_match_all, - preg_match_all_offset_capture, preg_match_all_set_order, preg_replace, + CaptureKey, php_regex, preg_match, preg_match_all, preg_match_all_offset_capture, + preg_match_all_set_order, preg_replace, }; use shirabe_symfony_string::b; @@ -109,9 +109,8 @@ impl OutputFormatter { return Ok(Some(style.borrow().clone_box())); } - let mut matches: Vec<Vec<Option<String>>> = vec![]; - if preg_match_all_set_order(php_regex!("/([^=]+)=([^;]+)(;|$)/"), string, &mut matches) == 0 - { + let matches = preg_match_all_set_order(php_regex!("/([^=]+)=([^;]+)(;|$)/"), string); + if matches.is_empty() { return Ok(None); } @@ -191,8 +190,7 @@ impl OutputFormatter { prefix = String::new(); } - let mut matches: Vec<Option<String>> = vec![]; - preg_match(php_regex!("~(\\n)$~"), &text, &mut matches); + let matches = preg_match(php_regex!("~(\\n)$~"), &text).unwrap_or_default(); text = format!("{}{}", prefix, self.add_line_breaks(&text, width)); let trailing = matches.get(1).and_then(|m| m.clone()).unwrap_or_default(); text = format!("{}{}", shirabe_php_shim::rtrim(&text, Some("\n")), trailing); @@ -294,11 +292,9 @@ impl WrappableOutputFormatterInterface for OutputFormatter { let open_tag_regex = "[a-z](?:[^\\\\<>]* | \\\\.)*"; let close_tag_regex = "[a-z][^<>]*"; let mut current_line_length: i64 = 0; - let mut matches = PregMatchesAllWithOffsets::new(); - preg_match_all_offset_capture( + let matches = preg_match_all_offset_capture( format!("#<(({open_tag_regex}) | /({close_tag_regex})?)>#ix"), message, - &mut matches, ); let full_matches = matches .get(&CaptureKey::ByIndex(0)) diff --git a/crates/shirabe-symfony-console/src/helper/helper.rs b/crates/shirabe-symfony-console/src/helper/helper.rs index 21f20d34..435648ca 100644 --- a/crates/shirabe-symfony-console/src/helper/helper.rs +++ b/crates/shirabe-symfony-console/src/helper/helper.rs @@ -40,7 +40,7 @@ impl Helper { /// Returns the width of a string, using mb_strwidth if it is available. /// The width is how many characters positions the string will use. pub fn width(string: &str) -> i64 { - if preg_match(php_regex!("//u"), string, &mut Vec::new()) { + if preg_match(php_regex!("//u"), string).is_some() { return UnicodeString::new(string).width(false); } @@ -56,7 +56,7 @@ impl Helper { /// Returns the length of a string, using mb_strlen if it is available. /// The length is related to how many bytes the string will use. pub fn length(string: &str) -> i64 { - if preg_match(php_regex!("//u"), string, &mut Vec::new()) { + if preg_match(php_regex!("//u"), string).is_some() { return UnicodeString::new(string).length(); } diff --git a/crates/shirabe-symfony-console/src/input/argv_input.rs b/crates/shirabe-symfony-console/src/input/argv_input.rs index b2b663a6..81582408 100644 --- a/crates/shirabe-symfony-console/src/input/argv_input.rs +++ b/crates/shirabe-symfony-console/src/input/argv_input.rs @@ -523,8 +523,7 @@ impl std::fmt::Display for ArgvInput { .tokens .iter() .map(|token| { - let mut r#match: Vec<Option<String>> = Vec::new(); - if preg_match(php_regex!("{^(-[^=]+=)(.+)}"), token, &mut r#match) { + if let Some(r#match) = preg_match(php_regex!("{^(-[^=]+=)(.+)}"), token) { return format!( "{}{}", r#match[1].as_deref().unwrap_or(""), diff --git a/crates/shirabe-symfony-console/src/input/input.rs b/crates/shirabe-symfony-console/src/input/input.rs index 89eedb03..4712a713 100644 --- a/crates/shirabe-symfony-console/src/input/input.rs +++ b/crates/shirabe-symfony-console/src/input/input.rs @@ -207,8 +207,7 @@ impl Input { /// Escapes a token through escapeshellarg if it contains unsafe chars. pub fn escape_token(&self, token: &str) -> String { - let mut matches: Vec<Option<String>> = vec![]; - if preg_match(php_regex!("{^[\\w-]+$}"), token, &mut matches) { + if preg_match(php_regex!("{^[\\w-]+$}"), token).is_some() { token.to_string() } else { shirabe_php_shim::escapeshellarg(token) diff --git a/crates/shirabe-symfony-console/src/input/string_input.rs b/crates/shirabe-symfony-console/src/input/string_input.rs index 245b948d..b0c3b159 100644 --- a/crates/shirabe-symfony-console/src/input/string_input.rs +++ b/crates/shirabe-symfony-console/src/input/string_input.rs @@ -6,7 +6,7 @@ use crate::input::InputDefinition; use crate::input::InputInterface; use crate::input::StreamableInputInterface; use indexmap::IndexMap; -use shirabe_php_shim::{CaptureKey, PhpMixed, PregMatches, php_regex, preg_match2}; +use shirabe_php_shim::{CaptureKey, PhpMixed, php_regex, preg_match2}; /// StringInput represents an input provided as a string. /// @@ -57,17 +57,15 @@ impl StringInput { continue; } - let mut m = PregMatches::new(); - if preg_match2(php_regex!(r"/\s+/A"), input, &mut m, cursor as usize) { + if let Some(m) = preg_match2(php_regex!(r"/\s+/A"), input, cursor as usize) { if token.is_some() { tokens.push(token.take().unwrap()); } cursor += shirabe_php_shim::strlen(m[&CaptureKey::ByIndex(0)].as_deref().unwrap_or("")); - } else if preg_match2( + } else if let Some(m) = preg_match2( format!(r#"/([^="'\s]+?)(=?)({}+)/A"#, Self::REGEX_QUOTED_STRING), input, - &mut m, cursor as usize, ) { let inner = shirabe_php_shim::substr( @@ -86,10 +84,9 @@ impl StringInput { )); cursor += shirabe_php_shim::strlen(m[&CaptureKey::ByIndex(0)].as_deref().unwrap_or("")); - } else if preg_match2( + } else if let Some(m) = preg_match2( format!(r"/{}/A", Self::REGEX_QUOTED_STRING), input, - &mut m, cursor as usize, ) { token = Some(format!( @@ -103,10 +100,9 @@ impl StringInput { )); cursor += shirabe_php_shim::strlen(m[&CaptureKey::ByIndex(0)].as_deref().unwrap_or("")); - } else if preg_match2( + } else if let Some(m) = preg_match2( format!(r"/{}/A", Self::REGEX_UNQUOTED_STRING), input, - &mut m, cursor as usize, ) { token = Some(format!( diff --git a/crates/shirabe-symfony-console/src/output/stream_output.rs b/crates/shirabe-symfony-console/src/output/stream_output.rs index 43cee3a8..14565012 100644 --- a/crates/shirabe-symfony-console/src/output/stream_output.rs +++ b/crates/shirabe-symfony-console/src/output/stream_output.rs @@ -120,14 +120,13 @@ impl StreamOutput { } // See https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js#L157 - let mut matches: Vec<Option<String>> = Vec::new(); preg_match( php_regex!( "/^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/" ), &term, - &mut matches, ) + .is_some() } } diff --git a/crates/shirabe-symfony-console/src/question/choice_question.rs b/crates/shirabe-symfony-console/src/question/choice_question.rs index b8ac16d8..84cba360 100644 --- a/crates/shirabe-symfony-console/src/question/choice_question.rs +++ b/crates/shirabe-symfony-console/src/question/choice_question.rs @@ -122,12 +122,12 @@ impl ChoiceQuestion { let selected_choices: Vec<PhpMixed> = if multiselect { // Check for a separated comma values - let mut matches: Vec<Option<String>> = Vec::new(); - if !preg_match( + if preg_match( php_regex!("/^[^,]+(?:,[^,]+)*$/"), &shirabe_php_shim::strval(&selected), - &mut matches, - ) { + ) + .is_none() + { return Err(InvalidArgumentException::new(shirabe_php_shim::sprintf( &error_message, std::slice::from_ref(&selected), diff --git a/crates/shirabe-symfony-console/src/question/confirmation_question.rs b/crates/shirabe-symfony-console/src/question/confirmation_question.rs index 6ec9281f..5a18a045 100644 --- a/crates/shirabe-symfony-console/src/question/confirmation_question.rs +++ b/crates/shirabe-symfony-console/src/question/confirmation_question.rs @@ -38,10 +38,7 @@ impl ConfirmationQuestion { return answer; } - let answer_is_true = { - let mut matches: Vec<Option<String>> = Vec::new(); - preg_match(®ex, &shirabe_php_shim::strval(&answer), &mut matches) - }; + let answer_is_true = preg_match(®ex, &shirabe_php_shim::strval(&answer)).is_some(); // false === $default if matches!(default, PhpMixed::Bool(false)) { diff --git a/crates/shirabe-symfony-console/src/terminal.rs b/crates/shirabe-symfony-console/src/terminal.rs index 8ff0431a..8db6fd93 100644 --- a/crates/shirabe-symfony-console/src/terminal.rs +++ b/crates/shirabe-symfony-console/src/terminal.rs @@ -79,12 +79,10 @@ impl Terminal { fn init_dimensions() { if cfg!(windows) { let ansicon = shirabe_php_shim::getenv("ANSICON"); - let mut matches: Vec<Option<String>> = Vec::new(); if let Some(ansicon) = &ansicon - && preg_match( + && let Some(matches) = preg_match( php_regex!("/^(\\d+)x(\\d+)(?: \\((\\d+)x(\\d+)\\))?$/"), &shirabe_php_shim::trim(&ansicon.to_string_lossy(), None), - &mut matches, ) { // extract [w, H] from "wxh (WxH)" @@ -137,12 +135,9 @@ impl Terminal { if stty_string.is_empty() { return; } - let mut matches: Vec<Option<String>> = Vec::new(); - if preg_match( - php_regex!("/rows.(\\d+);.columns.(\\d+);/i"), - &stty_string, - &mut matches, - ) { + if let Some(matches) = + preg_match(php_regex!("/rows.(\\d+);.columns.(\\d+);/i"), &stty_string) + { // extract [w, h] from "rows h; columns w;" WIDTH.with(|w| { w.set(Some(shirabe_php_shim::intval(&PhpMixed::String( @@ -154,11 +149,9 @@ impl Terminal { matches[1].clone().unwrap_or_default(), )))) }); - } else if preg_match( - php_regex!("/;.(\\d+).rows;.(\\d+).columns/i"), - &stty_string, - &mut matches, - ) { + } else if let Some(matches) = + preg_match(php_regex!("/;.(\\d+).rows;.(\\d+).columns/i"), &stty_string) + { // extract [w, h] from "; h rows; w columns" WIDTH.with(|w| { w.set(Some(shirabe_php_shim::intval(&PhpMixed::String( @@ -181,14 +174,10 @@ impl Terminal { let info = Self::read_from_process("mode CON"); let info = info?; - let mut matches: Vec<Option<String>> = Vec::new(); - if !preg_match( + let matches = preg_match( php_regex!("/--------+\\r?\\n.+?(\\d+)\\r?\\n.+?(\\d+)\\r?\\n/"), &info, - &mut matches, - ) { - return None; - } + )?; Some(vec![ shirabe_php_shim::intval(&PhpMixed::String(matches[2].clone().unwrap_or_default())), |
