aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/util
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-17 06:43:52 +0900
committernsfisis <nsfisis@gmail.com>2026-08-17 06:43:52 +0900
commit52a0665acbbe5bf5b8c6875118fb9cdf7952453b (patch)
tree7302b0b87f7b0d406126da734ef82c80abf64204 /crates/shirabe/src/util
parentc81e9f89d9e4388f36a4427bbaa95eced659d2ce (diff)
downloadphp-shirabe-52a0665acbbe5bf5b8c6875118fb9cdf7952453b.tar.gz
php-shirabe-52a0665acbbe5bf5b8c6875118fb9cdf7952453b.tar.zst
php-shirabe-52a0665acbbe5bf5b8c6875118fb9cdf7952453b.zip
refactor(preg): wrap the preg_* $matches maps in newtypes
The five IndexMap shapes that the preg_* functions and Preg fill in are now distinct types generated by preg_match_map!, so a matches map no longer interchanges with any other map of the same key and value type. Index<usize> is kept alongside Index<&Q> because call sites such as config_command and event_dispatcher reach for a group by its position in the map rather than by its capture key.
Diffstat (limited to 'crates/shirabe/src/util')
-rw-r--r--crates/shirabe/src/util/composer_mirror.rs6
-rw-r--r--crates/shirabe/src/util/filesystem.rs5
-rw-r--r--crates/shirabe/src/util/forgejo_url.rs3
-rw-r--r--crates/shirabe/src/util/git.rs16
-rw-r--r--crates/shirabe/src/util/github.rs4
-rw-r--r--crates/shirabe/src/util/hg.rs4
-rw-r--r--crates/shirabe/src/util/http/response.rs3
-rw-r--r--crates/shirabe/src/util/http_downloader.rs4
-rw-r--r--crates/shirabe/src/util/platform.rs4
-rw-r--r--crates/shirabe/src/util/process_executor.rs6
-rw-r--r--crates/shirabe/src/util/remote_filesystem.rs4
-rw-r--r--crates/shirabe/src/util/svn.rs5
-rw-r--r--crates/shirabe/src/util/url.rs9
13 files changed, 34 insertions, 39 deletions
diff --git a/crates/shirabe/src/util/composer_mirror.rs b/crates/shirabe/src/util/composer_mirror.rs
index 1e57662a..1455613d 100644
--- a/crates/shirabe/src/util/composer_mirror.rs
+++ b/crates/shirabe/src/util/composer_mirror.rs
@@ -1,6 +1,6 @@
//! ref: composer/src/Composer/Util/ComposerMirror.php
-use shirabe_pcre::{CaptureKey, Preg};
+use shirabe_pcre::{CaptureKey, Preg, PregMatchedGroups};
use shirabe_php_shim::{hash, php_regex};
pub struct ComposerMirror;
@@ -53,8 +53,8 @@ impl ComposerMirror {
url: &str,
r#type: Option<&str>,
) -> String {
- let mut gh_matches: indexmap::IndexMap<CaptureKey, String> = indexmap::IndexMap::new();
- let mut bb_matches: indexmap::IndexMap<CaptureKey, String> = indexmap::IndexMap::new();
+ let mut gh_matches = PregMatchedGroups::new();
+ let mut bb_matches = PregMatchedGroups::new();
let normalized_url = if Preg::match3(
php_regex!(
r"#^(?:(?:https?|git)://github\.com/|git@github\.com:)([^/]+)/(.+?)(?:\.git)?$#"
diff --git a/crates/shirabe/src/util/filesystem.rs b/crates/shirabe/src/util/filesystem.rs
index 1a9ab703..21512a81 100644
--- a/crates/shirabe/src/util/filesystem.rs
+++ b/crates/shirabe/src/util/filesystem.rs
@@ -735,8 +735,7 @@ impl Filesystem {
}
// extract a prefix being a protocol://, protocol:, protocol://drive: or simply drive:
- let mut prefix_match: indexmap::IndexMap<shirabe_pcre::CaptureKey, String> =
- indexmap::IndexMap::new();
+ let mut prefix_match = shirabe_pcre::PregMatchedGroups::new();
if Preg::is_match3(
php_regex!("{^( [0-9a-z]{2,}+: (?: // (?: [a-z]: )? )? | [a-z]: )}ix"),
&path,
@@ -768,7 +767,7 @@ impl Filesystem {
// ensure c: is normalized to C:
prefix = Preg::replace_callback(
php_regex!("{(^|://)[a-z]:$}i"),
- |m: &indexmap::IndexMap<shirabe_pcre::CaptureKey, String>| -> String {
+ |m: &shirabe_pcre::PregMatchedGroups| -> String {
let s = m
.get(&shirabe_pcre::CaptureKey::ByIndex(0))
.cloned()
diff --git a/crates/shirabe/src/util/forgejo_url.rs b/crates/shirabe/src/util/forgejo_url.rs
index d2628409..7a5d2b10 100644
--- a/crates/shirabe/src/util/forgejo_url.rs
+++ b/crates/shirabe/src/util/forgejo_url.rs
@@ -37,8 +37,7 @@ impl ForgejoUrl {
pub fn try_from(repo_url: Option<&str>) -> Option<Self> {
let repo_url = repo_url?;
- let mut matches: indexmap::IndexMap<shirabe_pcre::CaptureKey, String> =
- indexmap::IndexMap::new();
+ let mut matches = shirabe_pcre::PregMatchedGroups::new();
if !Preg::match3(Self::URL_REGEX, repo_url, Some(&mut matches)) {
return None;
}
diff --git a/crates/shirabe/src/util/git.rs b/crates/shirabe/src/util/git.rs
index f8fea562..0f463aea 100644
--- a/crates/shirabe/src/util/git.rs
+++ b/crates/shirabe/src/util/git.rs
@@ -14,7 +14,7 @@ use crate::util::ProcessExecutor;
use crate::util::Url;
use crate::util::{AuthHelper, StoreAuth};
use indexmap::IndexMap;
-use shirabe_pcre::{CaptureKey, Preg};
+use shirabe_pcre::{CaptureKey, Preg, PregMatchedGroups};
use shirabe_php_shim::{
AnyThrowable, CmpOp, InvalidArgumentException, PHP_EOL, PhpMixed, RuntimeException, array_map,
clearstatcache, explode, implode, in_array_loose, in_array_strict, is_dir, php_regex,
@@ -226,7 +226,7 @@ impl Git {
&mut output,
cwd,
)?;
- let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut m = PregMatchedGroups::new();
if Preg::is_match3(
php_regex!(r"{^(?:composer|origin)\s+https?://(.+):(.+)@([^/]+)}im"),
&output,
@@ -248,7 +248,7 @@ impl Git {
let protocols = self.config.borrow_mut().get("github-protocols");
// public github, autoswitch protocols
// @phpstan-ignore composerPcre.maybeUnsafeStrictGroups
- let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut m = PregMatchedGroups::new();
if Preg::is_match3(
format!(
"{{^(?:https?|git)://{}/(.*)}}",
@@ -344,7 +344,7 @@ impl Git {
let mut error_msg = self.process.borrow().get_error_output().to_string();
// private github repository without ssh key access, try https with auth
// @phpstan-ignore composerPcre.maybeUnsafeStrictGroups
- let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut m = PregMatchedGroups::new();
let github_matched = Preg::is_match3(
format!(
"{{^git@{}:(.+?)\\.git$}}i",
@@ -1089,8 +1089,8 @@ impl Git {
Ok(false)
}
- fn get_authentication_failure(&self, url: &str) -> Option<IndexMap<CaptureKey, String>> {
- let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ fn get_authentication_failure(&self, url: &str) -> Option<PregMatchedGroups> {
+ let mut m = PregMatchedGroups::new();
if !Preg::is_match3(
php_regex!(r"{^(https?://)([^/]+)(.*)$}i"),
url,
@@ -1179,7 +1179,7 @@ impl Git {
.borrow()
.split_lines(output_mixed.as_string().unwrap_or(""));
for line in lines {
- let mut matches: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut matches = PregMatchedGroups::new();
if Preg::is_match3(
php_regex!(r"{^\s*HEAD branch:\s(.+)\s*$}m"),
&line,
@@ -1308,7 +1308,7 @@ impl Git {
Option::<&str>::None,
);
if exit_code == 0 {
- let mut matches: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut matches = PregMatchedGroups::new();
if Preg::is_match3(
php_regex!(r"/^git version (\d+(?:\.\d+)+)/m"),
&output,
diff --git a/crates/shirabe/src/util/github.rs b/crates/shirabe/src/util/github.rs
index 25a95e57..b7659572 100644
--- a/crates/shirabe/src/util/github.rs
+++ b/crates/shirabe/src/util/github.rs
@@ -8,7 +8,7 @@ use crate::io::io_interface;
use crate::util::HttpDownloader;
use crate::util::ProcessExecutor;
use indexmap::IndexMap;
-use shirabe_pcre::{CaptureKey, Preg};
+use shirabe_pcre::{CaptureKey, Preg, PregMatchedGroups};
use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PhpMixed, date_local, in_array_loose, php_regex, stripos, strtolower};
@@ -325,7 +325,7 @@ impl GitHub {
if stripos(header, "x-github-sso: required").is_none() {
continue;
}
- let mut caps: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut caps = PregMatchedGroups::new();
if Preg::match3(
php_regex!(r"{\burl=(?P<url>[^\s;]+)}"),
header,
diff --git a/crates/shirabe/src/util/hg.rs b/crates/shirabe/src/util/hg.rs
index f0cc56cc..8570af6d 100644
--- a/crates/shirabe/src/util/hg.rs
+++ b/crates/shirabe/src/util/hg.rs
@@ -5,7 +5,7 @@ use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
use crate::util::ProcessExecutor;
use crate::util::Url;
-use shirabe_pcre::Preg;
+use shirabe_pcre::{Preg, PregNamedGroups};
use shirabe_php_shim::{php_regex, rawurlencode};
use std::sync::OnceLock;
@@ -56,7 +56,7 @@ impl Hg {
}
// Try with the authentication information available
- let mut matches: indexmap::IndexMap<String, String> = indexmap::IndexMap::new();
+ let mut matches = PregNamedGroups::new();
let matched = Preg::is_match_named(
php_regex!(
r"{^(?P<proto>ssh|https?)://(?:(?P<user>[^:@]+)(?::(?P<pass>[^:@]+))?@)?(?P<host>[^/]+)(?P<path>/.*)?}mi"
diff --git a/crates/shirabe/src/util/http/response.rs b/crates/shirabe/src/util/http/response.rs
index 47a1593f..6ce52643 100644
--- a/crates/shirabe/src/util/http/response.rs
+++ b/crates/shirabe/src/util/http/response.rs
@@ -65,8 +65,7 @@ impl Response {
let mut value = None;
let pattern = format!("{{^{}:\\s*(.+?)\\s*$}}i", preg_quote(name, None));
for header in headers {
- let mut matches: indexmap::IndexMap<shirabe_pcre::CaptureKey, String> =
- indexmap::IndexMap::new();
+ let mut matches = shirabe_pcre::PregMatchedGroups::new();
if Preg::match3(&pattern, header, Some(&mut matches))
&& let Some(s) = matches.get(&shirabe_pcre::CaptureKey::ByIndex(1))
{
diff --git a/crates/shirabe/src/util/http_downloader.rs b/crates/shirabe/src/util/http_downloader.rs
index c8fb943b..c478d445 100644
--- a/crates/shirabe/src/util/http_downloader.rs
+++ b/crates/shirabe/src/util/http_downloader.rs
@@ -16,7 +16,7 @@ use crate::util::http::CurlDownloader;
use crate::util::http::Response;
use crate::util::sync_executor;
use indexmap::IndexMap;
-use shirabe_pcre::{CaptureKey, Preg};
+use shirabe_pcre::{CaptureKey, Preg, PregMatchedGroups};
use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, LogicException, PhpMixed, array_replace_recursive, extension_loaded,
@@ -240,7 +240,7 @@ impl HttpDownloader {
let origin = Url::get_origin(&self.config.borrow(), url);
// capture username/password from URL if there is one
- let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut m = PregMatchedGroups::new();
if Preg::is_match3(
php_regex!(r"{^https?://([^:/]+):([^@/]+)@([^/]+)}i"),
url,
diff --git a/crates/shirabe/src/util/platform.rs b/crates/shirabe/src/util/platform.rs
index 4336de53..21ad869c 100644
--- a/crates/shirabe/src/util/platform.rs
+++ b/crates/shirabe/src/util/platform.rs
@@ -2,7 +2,7 @@
use crate::util::ProcessExecutor;
use crate::util::Silencer;
-use shirabe_pcre::Preg;
+use shirabe_pcre::{Preg, PregMatchedGroups};
use shirabe_php_shim::{
PHP_ENV, PHP_SERVER, PhpMixed, PhpResource, RuntimeException, defined, file_exists,
file_get_contents, fstat, function_exists, getcwd, getenv, ini_get, is_readable, mb_strlen,
@@ -99,7 +99,7 @@ impl Platform {
// not participate is reported as an empty string, which `\w+` can never capture.
Preg::replace_callback(
php_regex!(r"#^(?:\$(?P<dvar>\w+)|%(?P<pvar>\w+)%)(?P<path>.*)#"),
- |matches: &indexmap::IndexMap<CaptureKey, String>| -> String {
+ |matches: &PregMatchedGroups| -> String {
let var = matches
.get(&CaptureKey::ByName("dvar".to_string()))
.filter(|dvar| !dvar.is_empty())
diff --git a/crates/shirabe/src/util/process_executor.rs b/crates/shirabe/src/util/process_executor.rs
index fc67604e..d87e2ff4 100644
--- a/crates/shirabe/src/util/process_executor.rs
+++ b/crates/shirabe/src/util/process_executor.rs
@@ -7,7 +7,7 @@ use crate::signal::SignalSubscription;
use crate::util::GitHub;
use crate::util::Platform;
use indexmap::IndexMap;
-use shirabe_pcre::{CaptureKey, Preg};
+use shirabe_pcre::{CaptureKey, Preg, PregMatchedGroups};
use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
LogicException, PHP_EOL, PhpMixed, RuntimeException, array_intersect, array_map,
@@ -217,7 +217,7 @@ impl ProcessExecutor {
if is_string(&command) {
let mut command_str = command.as_string().unwrap_or("").to_string();
if Platform::is_windows() {
- let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut m = PregMatchedGroups::new();
if Preg::is_match3(php_regex!(r"{^([^:/\\]++) }"), &command_str, Some(&mut m)) {
let m1 = m.get(&CaptureKey::ByIndex(1)).cloned().unwrap_or_default();
command_str = substr_replace(
@@ -832,7 +832,7 @@ impl ProcessExecutor {
};
let safe_command = Preg::replace_callback(
php_regex!(r"{://(?P<user>[^:/\s]+):(?P<password>[^@\s/]+)@}i"),
- |m: &IndexMap<CaptureKey, String>| -> String {
+ |m: &PregMatchedGroups| -> String {
let user_key = CaptureKey::ByName("user".to_string());
// if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx, github_pat_xxx) we obfuscate that
if Preg::is_match(
diff --git a/crates/shirabe/src/util/remote_filesystem.rs b/crates/shirabe/src/util/remote_filesystem.rs
index 4a8ca267..40a69f28 100644
--- a/crates/shirabe/src/util/remote_filesystem.rs
+++ b/crates/shirabe/src/util/remote_filesystem.rs
@@ -13,7 +13,7 @@ use crate::util::Url;
use crate::util::http::ProxyManager;
use crate::util::http::Response;
use indexmap::IndexMap;
-use shirabe_pcre::{CaptureKey, Preg};
+use shirabe_pcre::{CaptureKey, Preg, PregMatchedGroups};
use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PhpMixed, RuntimeException, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_FILE_SIZE_IS,
@@ -148,7 +148,7 @@ impl RemoteFilesystem {
pub fn find_status_code(headers: &[String]) -> Option<i64> {
let mut value: Option<i64> = None;
for header in headers {
- let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut m = PregMatchedGroups::new();
if Preg::is_match3(php_regex!("{^HTTP/\\S+ (\\d+)}i"), header, Some(&mut m)) {
value = m
.get(&CaptureKey::ByIndex(1))
diff --git a/crates/shirabe/src/util/svn.rs b/crates/shirabe/src/util/svn.rs
index 9662c24d..d07b3ffe 100644
--- a/crates/shirabe/src/util/svn.rs
+++ b/crates/shirabe/src/util/svn.rs
@@ -6,8 +6,7 @@ use crate::io::IOInterfaceImmutable;
use crate::io::io_interface;
use crate::util::Platform;
use crate::util::ProcessExecutor;
-use indexmap::IndexMap;
-use shirabe_pcre::{CaptureKey, Preg};
+use shirabe_pcre::{CaptureKey, Preg, PregMatchedGroups};
use shirabe_php_shim::{
LogicException, PhpMixed, RuntimeException, implode, parse_url, php_regex, stripos, strpos,
trim,
@@ -407,7 +406,7 @@ impl Svn {
&mut output,
None,
) {
- let mut matches: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut matches = PregMatchedGroups::new();
if Preg::is_match3(
php_regex!(r"{(\d+(?:\.\d+)+)}"),
&output,
diff --git a/crates/shirabe/src/util/url.rs b/crates/shirabe/src/util/url.rs
index ea9e4401..3afcd962 100644
--- a/crates/shirabe/src/util/url.rs
+++ b/crates/shirabe/src/util/url.rs
@@ -2,8 +2,7 @@
use crate::config::Config;
use crate::util::GitHub;
-use indexmap::IndexMap;
-use shirabe_pcre::{CaptureKey, Preg};
+use shirabe_pcre::{CaptureKey, Preg, PregMatchedGroups};
use shirabe_php_shim::{PhpMixed, in_array_strict, parse_url, php_regex};
pub struct Url;
@@ -15,7 +14,7 @@ impl Url {
.unwrap_or_default();
if host == "api.github.com" || host == "github.com" || host == "www.github.com" {
- let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut m = PregMatchedGroups::new();
if Preg::match3(
php_regex!(
r"{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/(zip|tar)ball/(.+)$}i"
@@ -60,7 +59,7 @@ impl Url {
);
}
} else if host == "bitbucket.org" || host == "www.bitbucket.org" {
- let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut m = PregMatchedGroups::new();
if Preg::match3(
php_regex!(
r"{^https?://(?:www\.)?bitbucket\.org/([^/]+)/([^/]+)/get/(.+)\.(zip|tar\.gz|tar\.bz2)$}i"
@@ -77,7 +76,7 @@ impl Url {
);
}
} else if host == "gitlab.com" || host == "www.gitlab.com" {
- let mut m: IndexMap<CaptureKey, String> = IndexMap::new();
+ let mut m = PregMatchedGroups::new();
if Preg::match3(
php_regex!(
r"{^https?://(?:www\.)?gitlab\.com/api/v[34]/projects/([^/]+)/repository/archive\.(zip|tar\.gz|tar\.bz2|tar)\?sha=.+$}i"