use std::{
borrow::Cow,
path::{Path, PathBuf},
};
use crate::config::package::PackageConfig;
pub fn normalize_path(path: &str) -> Cow<'_, str> {
if path.contains('\\') || path.contains("./") {
Cow::Owned(path.replace("\\", "/").replace("./", ""))
} else {
Cow::Borrowed(path)
}
}
pub fn normalize_package_paths(package: &PackageConfig) -> (PathBuf, PathBuf) {
let mut normalized_root = normalize_path(&package.workspace_root);
if normalized_root == "." {
normalized_root = Cow::from("");
}
let normalized_workspace_root =
Path::new(normalized_root.as_ref()).to_path_buf();
let full_path = normalized_workspace_root
.join(&package.path)
.to_string_lossy()
.to_string();
let mut normalized_full = normalize_path(&full_path);
if normalized_full == "." {
normalized_full = Cow::from("");
}
let normalized_full_path =
Path::new(normalized_full.as_ref()).to_path_buf();
(normalized_workspace_root, normalized_full_path)
}
pub fn normalize_additional_paths(package: &PackageConfig) -> Vec<PathBuf> {
package
.additional_paths
.clone()
.unwrap_or_default()
.iter()
.map(|p| {
let normalized = normalize_path(p).to_string();
if normalized == "." {
Path::new("").to_path_buf()
} else {
Path::new(&normalized).to_path_buf()
}
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn returns_borrowed_for_clean_paths() {
let path = "src/main.rs";
let result = normalize_path(path);
assert!(matches!(result, Cow::Borrowed(_)));
assert_eq!(result, "src/main.rs");
}
#[test]
fn normalizes_windows_paths() {
assert_eq!(normalize_path("src\\main.rs"), "src/main.rs");
}
#[test]
fn removes_dot_slash_at_start() {
assert_eq!(normalize_path("./src/main.rs"), "src/main.rs");
}
#[test]
fn removes_dot_slash_in_middle() {
assert_eq!(
normalize_path("packages/./api/src/main.rs"),
"packages/api/src/main.rs"
);
}
#[test]
fn handles_multiple_issues() {
assert_eq!(normalize_path(".\\packages\\.\\api"), "packages/api");
}
#[test]
fn handles_empty_path() {
assert_eq!(normalize_path(""), "");
}
}