diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-16 17:58:11 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-16 17:58:11 +0900 |
| commit | 24a4f39bd981768cc299121b506f6bba584cb31d (patch) | |
| tree | 39c9de717f5ca374e2c4df9b7eaeb0f86b11da0b /crates/shirabe-php-shim/src | |
| parent | 224d3e8262ed6156ea3374fe91dfb5b66d6f0d3a (diff) | |
| download | php-shirabe-24a4f39bd981768cc299121b506f6bba584cb31d.tar.gz php-shirabe-24a4f39bd981768cc299121b506f6bba584cb31d.tar.zst php-shirabe-24a4f39bd981768cc299121b506f6bba584cb31d.zip | |
refactor(preg): merge preg_replace_callback2 into preg_replace_callback
preg_replace_callback2 had one caller, Preg::replace_callback6, which
was itself reached only from Preg::replace_callback with the default
limit, count and flags. Fold the two shim functions into one and drop
those parameters along with replace_callback6.
The surviving callback takes callback2's IndexMap of matches: it can be
keyed by group name, and it omits trailing non-participating groups the
way PHP does, which is what the callbacks in Process and ProgressBar
test for.
Diffstat (limited to 'crates/shirabe-php-shim/src')
| -rw-r--r-- | crates/shirabe-php-shim/src/preg.rs | 56 |
1 files changed, 7 insertions, 49 deletions
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, |
