diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-06-21 15:49:24 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-06-21 15:49:37 +0900 |
| commit | fcef25f6ef36287a4984ffdaab39df84f5aceeba (patch) | |
| tree | 97ceb2098fbb5642e858929da9578bb41e277ada /crates/shirabe-php-shim/src/url.rs | |
| parent | f0f5f084c883dc4f5b6e61603e82cd1c2092fd9d (diff) | |
| download | php-shirabe-fcef25f6ef36287a4984ffdaab39df84f5aceeba.tar.gz php-shirabe-fcef25f6ef36287a4984ffdaab39df84f5aceeba.tar.zst php-shirabe-fcef25f6ef36287a4984ffdaab39df84f5aceeba.zip | |
refactor(php-shim): split lib.rs
Diffstat (limited to 'crates/shirabe-php-shim/src/url.rs')
| -rw-r--r-- | crates/shirabe-php-shim/src/url.rs | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/crates/shirabe-php-shim/src/url.rs b/crates/shirabe-php-shim/src/url.rs new file mode 100644 index 0000000..ddb46b6 --- /dev/null +++ b/crates/shirabe-php-shim/src/url.rs @@ -0,0 +1,91 @@ +use crate::PhpMixed; +use indexmap::IndexMap; + +pub const PHP_URL_SCHEME: i64 = 0; +pub const PHP_URL_HOST: i64 = 1; +pub const PHP_URL_PORT: i64 = 2; +pub const PHP_URL_USER: i64 = 3; +pub const PHP_URL_PASS: i64 = 4; +pub const PHP_URL_PATH: i64 = 5; +pub const PHP_URL_QUERY: i64 = 6; +pub const PHP_URL_FRAGMENT: i64 = 7; + +pub fn parse_url(url: &str, component: i64) -> PhpMixed { + let all = parse_url_all(url); + let map = match all.as_array() { + Some(map) => map, + // parse_url_all already collapsed a malformed URL to false; propagate it. + None => return all, + }; + let key = match component { + PHP_URL_SCHEME => "scheme", + PHP_URL_HOST => "host", + PHP_URL_PORT => "port", + PHP_URL_USER => "user", + PHP_URL_PASS => "pass", + PHP_URL_PATH => "path", + PHP_URL_QUERY => "query", + PHP_URL_FRAGMENT => "fragment", + _ => return PhpMixed::Null, + }; + map.get(key).cloned().unwrap_or(PhpMixed::Null) +} + +pub fn parse_url_all(url: &str) -> PhpMixed { + // TODO(phase-c): PHP's parse_url uses php_url_parse_ex, which accepts relative + // and partial URLs and leaves an absent component absent. reqwest::Url + // (WHATWG/RFC 3986) requires an absolute URL, lowercases the host of special + // schemes, and normalizes the path (e.g. "http://host" yields path "/"). This + // is therefore not a byte-for-byte compatible port of parse_url. + let parsed = match reqwest::Url::parse(url) { + Ok(parsed) => parsed, + Err(_) => return PhpMixed::Bool(false), + }; + let mut map: IndexMap<String, PhpMixed> = IndexMap::new(); + map.insert( + "scheme".to_string(), + PhpMixed::String(parsed.scheme().to_string()), + ); + if let Some(host) = parsed.host_str() { + map.insert("host".to_string(), PhpMixed::String(host.to_string())); + } + if let Some(port) = parsed.port() { + map.insert("port".to_string(), PhpMixed::Int(port as i64)); + } + if !parsed.username().is_empty() { + map.insert( + "user".to_string(), + PhpMixed::String(parsed.username().to_string()), + ); + } + if let Some(pass) = parsed.password() { + map.insert("pass".to_string(), PhpMixed::String(pass.to_string())); + } + let path = parsed.path(); + if !path.is_empty() { + map.insert("path".to_string(), PhpMixed::String(path.to_string())); + } + if let Some(query) = parsed.query() { + map.insert("query".to_string(), PhpMixed::String(query.to_string())); + } + if let Some(fragment) = parsed.fragment() { + map.insert( + "fragment".to_string(), + PhpMixed::String(fragment.to_string()), + ); + } + PhpMixed::Array(map) +} + +pub fn http_build_query_mixed( + data: &IndexMap<String, PhpMixed>, + numeric_prefix: &str, + arg_separator: &str, +) -> String { + let _ = (data, numeric_prefix, arg_separator); + todo!() +} + +pub fn http_build_query(_data: &[(&str, &str)], _sep_str: &str, _sep: &str) -> String { + todo!() +} |
