use url::Url;
#[cfg(not(target_arch = "wasm32"))]
pub fn normalize_uri(uri: &str) -> String {
let trimmed = uri.trim();
if trimmed.is_empty() {
return String::new();
}
if let Some(normalized) = crate::classify::normalize_legacy_windows_uri(trimmed) {
return normalized;
}
let path = std::path::Path::new(trimmed);
if path.is_absolute()
&& let Ok(uri_string) = crate::fs_path_to_uri(path)
{
return uri_string;
}
if let Ok(url) = Url::parse(trimmed) {
if should_canonicalize_local_file_authority(&url) {
return crate::classify::uri_key(trimmed);
}
return url.to_string();
}
if let Ok(uri_string) = crate::fs_path_to_uri(path) {
return uri_string;
}
if trimmed.starts_with("file://")
&& let Some(fs_path) = crate::uri_to_fs_path(trimmed)
&& let Ok(normalized) = crate::fs_path_to_uri(&fs_path)
{
return normalized;
}
trimmed.to_string()
}
#[cfg(not(target_arch = "wasm32"))]
fn should_canonicalize_local_file_authority(url: &Url) -> bool {
url.scheme() == "file" && crate::classify::is_local_file_authority(url.host_str())
}
#[cfg(target_arch = "wasm32")]
pub fn normalize_uri(uri: &str) -> String {
let trimmed = uri.trim();
if trimmed.is_empty() {
return String::new();
}
if let Some(normalized) = crate::classify::normalize_legacy_windows_uri(trimmed) {
return normalized;
}
if let Ok(url) = Url::parse(trimmed) { url.to_string() } else { trimmed.to_string() }
}
#[cfg(all(test, not(target_arch = "wasm32")))]
mod tests {
use super::*;
#[test]
fn local_file_authority_predicate_boundaries() -> Result<(), Box<dyn std::error::Error>> {
let cases = [
("file://127.0.0.1/tmp/module.pm", true, "file:///tmp/module.pm"),
("file://example.com/tmp/module.pm", false, "file://example.com/tmp/module.pm"),
("https://localhost/tmp/module.pm", false, "https://localhost/tmp/module.pm"),
];
for (input, expected_branch, expected_normalized) in cases {
let url = Url::parse(input)?;
assert_eq!(should_canonicalize_local_file_authority(&url), expected_branch);
assert_eq!(normalize_uri(input), expected_normalized);
}
Ok(())
}
}