diff options
| -rw-r--r-- | crates/shirabe-pcre/src/preg.rs | 18 | ||||
| -rw-r--r-- | crates/shirabe-php-shim/src/preg.rs | 56 | ||||
| -rw-r--r-- | crates/shirabe-symfony-console/src/helper/progress_bar.rs | 9 | ||||
| -rw-r--r-- | crates/shirabe-symfony-process/src/process.rs | 16 |
4 files changed, 26 insertions, 73 deletions
diff --git a/crates/shirabe-pcre/src/preg.rs b/crates/shirabe-pcre/src/preg.rs index 06586d2c..1c6fbfc1 100644 --- a/crates/shirabe-pcre/src/preg.rs +++ b/crates/shirabe-pcre/src/preg.rs @@ -156,25 +156,15 @@ impl Preg { pub fn replace_callback<F: FnMut(&IndexMap<CaptureKey, String>) -> String>( pattern: impl PregPattern, - replacement: F, - subject: &str, - ) -> String { - Self::replace_callback6(pattern, replacement, subject, -1, None, 0) - } - - pub fn replace_callback6<F: FnMut(&IndexMap<CaptureKey, String>) -> String>( - pattern: impl PregPattern, mut replacement: F, subject: &str, - limit: i64, - count: Option<&mut usize>, - flags: i64, ) -> String { - let adapter = |internal: &IndexMap<CaptureKey, Option<String>>| -> String { - replacement(&drop_null_matches_ref(internal)) + let adapter = |internal: &IndexMap<CaptureKey, Option<String>>| { + Ok(replacement(&drop_null_matches_ref(internal))) }; - shirabe_php_shim::preg_replace_callback2(pattern, adapter, subject, limit, count, flags) + shirabe_php_shim::preg_replace_callback(pattern, adapter, subject) + .expect("$replacement cannot fail") } pub fn split(pattern: impl PregPattern, subject: &str) -> Vec<String> { diff --git a/crates/shirabe-php-shim/src/preg.rs b/crates/shirabe-php-shim/src/preg.rs index b0828667..56801ca9 100644 --- a/crates/shirabe-php-shim/src/preg.rs +++ b/crates/shirabe-php-shim/src/preg.rs @@ -154,23 +154,23 @@ pub fn preg_replace_callback<F>( subject: &str, ) -> anyhow::Result<String> where - F: FnMut(&[Option<String>]) -> anyhow::Result<String>, + F: FnMut(&indexmap::IndexMap<CaptureKey, Option<String>>) -> anyhow::Result<String>, { let __resolved = pattern.resolve(); let (re, _anchored) = __resolved.parts(); + let names: Vec<Option<&str>> = re.capture_names().collect(); + let mut out: Vec<u8> = Vec::new(); - let mut last = 0; + let mut last = 0usize; for caps in re.captures_iter(subject) { let m = caps.get(0).unwrap(); out.extend_from_slice(&subject.as_bytes()[last..m.start()]); - let groups: Vec<Option<String>> = (0..caps.len()) - .map(|g| caps.get(g).map(|x| x.as_str().to_string())) - .collect(); - let replaced = callback(&groups)?; - out.extend_from_slice(replaced.as_bytes()); + let map = single_match_map(&caps, &names, false); + out.extend_from_slice(callback(&map)?.as_bytes()); last = m.end(); } out.extend_from_slice(&subject.as_bytes()[last..]); + Ok(String::from_utf8_lossy(&out).into_owned()) } @@ -318,48 +318,6 @@ pub fn preg_replace2( String::from_utf8_lossy(&out).into_owned() } -pub fn preg_replace_callback2< - F: FnMut(&indexmap::IndexMap<CaptureKey, Option<String>>) -> String, ->( - pattern: impl PregPattern, - mut callback: F, - subject: &str, - limit: i64, - count: Option<&mut usize>, - flags: i64, -) -> String { - let __resolved = pattern.resolve(); - let (re, _anchored) = __resolved.parts(); - let unmatched_as_null = flags & PREG_UNMATCHED_AS_NULL != 0; - let names: Vec<Option<&str>> = re.capture_names().collect(); - let limit = if limit < 0 { - usize::MAX - } else { - limit as usize - }; - - let mut out: Vec<u8> = Vec::new(); - let mut last = 0usize; - let mut n = 0usize; - for caps in re.captures_iter(subject) { - if n >= limit { - break; - } - let m = caps.get(0).unwrap(); - out.extend_from_slice(&subject.as_bytes()[last..m.start()]); - let map = single_match_map(&caps, &names, unmatched_as_null); - out.extend_from_slice(callback(&map).as_bytes()); - last = m.end(); - n += 1; - } - out.extend_from_slice(&subject.as_bytes()[last..]); - - if let Some(count) = count { - *count = n; - } - String::from_utf8_lossy(&out).into_owned() -} - pub fn preg_split2( pattern: impl PregPattern, subject: &str, diff --git a/crates/shirabe-symfony-console/src/helper/progress_bar.rs b/crates/shirabe-symfony-console/src/helper/progress_bar.rs index b0124419..dea1c3ad 100644 --- a/crates/shirabe-symfony-console/src/helper/progress_bar.rs +++ b/crates/shirabe-symfony-console/src/helper/progress_bar.rs @@ -9,6 +9,7 @@ use crate::output::OutputInterface; use crate::output::output_interface; use crate::terminal::Terminal; use indexmap::IndexMap; +use shirabe_php_shim::CaptureKey; pub const FORMAT_VERBOSE: &str = "verbose"; pub const FORMAT_VERY_VERBOSE: &str = "very_verbose"; @@ -797,8 +798,8 @@ impl ProgressBar { let format = self.format.clone().unwrap_or_default(); // $callback in PHP, expressed as a closure over $this and the matches. - let callback = |matches: &[Option<String>]| -> anyhow::Result<String> { - let name = matches[1].clone().unwrap_or_default(); + let callback = |matches: &IndexMap<CaptureKey, Option<String>>| -> anyhow::Result<String> { + let name = matches[&CaptureKey::ByIndex(1)].clone().unwrap_or_default(); let text: shirabe_php_shim::PhpMixed = if Self::get_placeholder_formatter_definition(&name).is_some() { @@ -812,10 +813,10 @@ impl ProgressBar { } else if let Some(message) = self.messages.get(&name) { shirabe_php_shim::PhpMixed::String(message.clone()) } else { - return Ok(matches[0].clone().unwrap_or_default()); + return Ok(matches[&CaptureKey::ByIndex(0)].clone().unwrap_or_default()); }; - if let Some(modifier) = matches.get(2).and_then(|m| m.clone()) { + if let Some(modifier) = matches.get(&CaptureKey::ByIndex(2)).and_then(|m| m.clone()) { return Ok(shirabe_php_shim::sprintf(&format!("%{modifier}"), &[text])); } diff --git a/crates/shirabe-symfony-process/src/process.rs b/crates/shirabe-symfony-process/src/process.rs index 87c6c68d..556238cf 100644 --- a/crates/shirabe-symfony-process/src/process.rs +++ b/crates/shirabe-symfony-process/src/process.rs @@ -11,7 +11,7 @@ use crate::pipes::unix_pipes::UnixPipes; use crate::pipes::windows_pipes::WindowsPipes; use crate::process_utils::ProcessUtils; use indexmap::IndexMap; -use shirabe_php_shim::{Descriptor, PhpMixed, PhpResource, php_regex}; +use shirabe_php_shim::{CaptureKey, Descriptor, PhpMixed, PhpResource, php_regex}; use std::sync::OnceLock; /// A user-supplied callback invoked with the output type ("out"/"err") and a chunk of output. @@ -935,9 +935,9 @@ impl Process { )++ ) | [^"]*+ )"/x"# ), - |m: &[Option<String>]| -> anyhow::Result<String> { - let m0 = m.first().cloned().flatten().unwrap_or_default(); - let m1 = m.get(1).cloned().flatten(); + |m: &IndexMap<CaptureKey, Option<String>>| -> anyhow::Result<String> { + let m0 = m[&CaptureKey::ByIndex(0)].clone().unwrap_or_default(); + let m1 = m.get(&CaptureKey::ByIndex(1)).cloned().flatten(); if m1.is_none() { return Ok(m0); } @@ -1073,8 +1073,12 @@ impl Process { ) -> anyhow::Result<String> { shirabe_php_shim::preg_replace_callback( php_regex!(r#"/"\$\{:([_a-zA-Z]+[_a-zA-Z0-9]*)\}"/"#), - |matches: &[Option<String>]| -> anyhow::Result<String> { - let key = matches.get(1).cloned().flatten().unwrap_or_default(); + |matches: &IndexMap<CaptureKey, Option<String>>| -> anyhow::Result<String> { + let key = matches + .get(&CaptureKey::ByIndex(1)) + .cloned() + .flatten() + .unwrap_or_default(); match env.get(&key) { None => Err(InvalidArgumentException::new(format!( "Command line is missing a value for parameter \"{}\": {}", |
