aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-pcre/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-18 01:57:02 +0900
committernsfisis <nsfisis@gmail.com>2026-08-18 01:57:02 +0900
commit844097edf44bf1424d28e2d5fbefda90c1c8f46c (patch)
tree968767db86e26acb022dd6ec5ac2c602d92e3708 /crates/shirabe-pcre/src
parent5114a8199a87c9e5584d92848e95deba22b73e98 (diff)
downloadphp-shirabe-844097edf44bf1424d28e2d5fbefda90c1c8f46c.tar.gz
php-shirabe-844097edf44bf1424d28e2d5fbefda90c1c8f46c.tar.zst
php-shirabe-844097edf44bf1424d28e2d5fbefda90c1c8f46c.zip
refactor(pcre): hand back the match instead of copying it out
Preg::match4 and Preg::replace_callback gave callers a PregMatchedGroups: an IndexMap rebuilt from the match with an owned String per group, plus a second String for a named group's name key. That is the copy PregMatches shed when it started wrapping regex::Captures, reinstated one layer up -- and nearly every regex call in the tree goes through Preg rather than the shim's preg_* directly, so almost nothing saw the borrow. PregMatchedGroups existed only to drop the null (unmatched) groups the old PregMatches held as Option<String> values. PregMatches::get reports a non-participating group as None on its own, so the two read alike and the type collapses into it. Call sites still reach groups through get(&CaptureKey::ByIndex(N)); what changes is that the value arrives as a &str borrowed from the subject, which the signatures now carry as a lifetime. Three places needed the borrow reckoned with rather than a mechanical rewrite: PhpFileCleaner::clean and Problem::get_messages read their groups out before mutating what the match borrows, and Git::get_authentication_failure names the lifetime of its url argument, which the result borrows instead of self. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-pcre/src')
-rw-r--r--crates/shirabe-pcre/src/preg.rs39
1 files changed, 12 insertions, 27 deletions
diff --git a/crates/shirabe-pcre/src/preg.rs b/crates/shirabe-pcre/src/preg.rs
index f3bfeac0..491e5371 100644
--- a/crates/shirabe-pcre/src/preg.rs
+++ b/crates/shirabe-pcre/src/preg.rs
@@ -18,12 +18,6 @@ use shirabe_php_shim::{
};
preg_match_map! {
- /// A single match's `$matches` as `Preg` hands it to callers: an unmatched capture group is
- /// absent rather than held as a null value.
- pub struct PregMatchedGroups(CaptureKey => String);
-}
-
-preg_match_map! {
/// The named capture groups of a single match, keyed by group name alone.
pub struct PregNamedGroups(String => String);
}
@@ -32,16 +26,16 @@ preg_match_map! {
pub struct Preg;
impl Preg {
- pub fn match3(pattern: impl PregPattern, subject: &str) -> Option<PregMatchedGroups> {
+ pub fn match3<'h>(pattern: impl PregPattern, subject: &'h str) -> Option<PregMatches<'h>> {
Self::match4(pattern, subject, 0)
}
- pub fn match4(
+ pub fn match4<'h>(
pattern: impl PregPattern,
- subject: &str,
+ subject: &'h str,
offset: usize,
- ) -> Option<PregMatchedGroups> {
- preg_match2(pattern, subject, offset).map(|internal| drop_null_matches(&internal))
+ ) -> Option<PregMatches<'h>> {
+ preg_match2(pattern, subject, offset)
}
pub fn match_all(pattern: impl PregPattern, subject: &str) -> usize {
@@ -82,12 +76,12 @@ impl Preg {
preg_replace2(pattern, replacement, subject, limit, Some(count))
}
- pub fn replace_callback<F: FnMut(&PregMatchedGroups) -> String>(
+ pub fn replace_callback<'h, F: FnMut(&PregMatches<'h>) -> String>(
pattern: impl PregPattern,
mut replacement: F,
- subject: &str,
+ subject: &'h str,
) -> String {
- let adapter = |internal: &PregMatches| Ok(replacement(&drop_null_matches(internal)));
+ let adapter = |matches: &PregMatches<'h>| Ok(replacement(matches));
preg_replace_callback(pattern, adapter, subject).expect("$replacement cannot fail")
}
@@ -103,15 +97,15 @@ impl Preg {
Self::match4(pattern, subject, 0).is_some()
}
- pub fn is_match3(pattern: impl PregPattern, subject: &str) -> Option<PregMatchedGroups> {
+ pub fn is_match3<'h>(pattern: impl PregPattern, subject: &'h str) -> Option<PregMatches<'h>> {
Self::match4(pattern, subject, 0)
}
- pub fn is_match4(
+ pub fn is_match4<'h>(
pattern: impl PregPattern,
- subject: &str,
+ subject: &'h str,
offset: usize,
- ) -> Option<PregMatchedGroups> {
+ ) -> Option<PregMatches<'h>> {
Self::match4(pattern, subject, offset)
}
@@ -155,12 +149,3 @@ impl Preg {
Self::match_all_with_offsets5(pattern, subject)
}
}
-
-// Drops `null` (unmatched) groups, mirroring how the public `string`-valued
-// `matches` map represents PHP's `string|null` entries by their absence.
-fn drop_null_matches(matches: &PregMatches) -> PregMatchedGroups {
- matches
- .iter()
- .filter_map(|(key, value)| value.map(|value| (key, value.to_string())))
- .collect()
-}