use std::{
borrow::Cow,
path::{Path, PathBuf},
};
use rolldown_std_utils::PathExt;
use crate::concat_string;
pub fn node_style_absolute<'a>(path: &'a Path, cwd: &Path) -> Option<Cow<'a, Path>> {
if path.is_absolute() {
return Some(Cow::Borrowed(path));
}
if !path.has_root() {
return None;
}
let std::path::Component::Prefix(prefix) = cwd.components().next()? else {
return None;
};
let path = path.expect_to_str();
let glued = match prefix.kind() {
std::path::Prefix::Disk(drive) | std::path::Prefix::VerbatimDisk(drive) => {
concat_string!(char::from(drive).to_string(), ":", path)
}
std::path::Prefix::UNC(server, share) | std::path::Prefix::VerbatimUNC(server, share) => {
concat_string!(r"\\", server.to_str()?, r"\", share.to_str()?, path)
}
_ => return None,
};
Some(Cow::Owned(PathBuf::from(glued)))
}
#[test]
fn test_node_style_absolute() {
assert_eq!(node_style_absolute(Path::new("src/a.js"), Path::new("/cwd")), None);
assert_eq!(node_style_absolute(Path::new("react"), Path::new("/cwd")), None);
#[cfg(not(target_os = "windows"))]
{
let p = Path::new("/favicon");
assert!(matches!(node_style_absolute(p, Path::new("/cwd")), Some(Cow::Borrowed(_))));
}
#[cfg(target_os = "windows")]
{
let p = Path::new(r"E:\proj\a.js");
assert!(matches!(node_style_absolute(p, Path::new(r"C:\cwd")), Some(Cow::Borrowed(_))));
assert_eq!(
node_style_absolute(Path::new("/favicon"), Path::new(r"E:\proj")).as_deref(),
Some(Path::new("E:/favicon"))
);
assert_eq!(
node_style_absolute(Path::new(r"\a\b"), Path::new(r"C:\x")).as_deref(),
Some(Path::new(r"C:\a\b"))
);
assert_eq!(
node_style_absolute(Path::new("/favicon"), Path::new(r"\\server\share\project")).as_deref(),
Some(Path::new(r"\\server\share/favicon"))
);
assert_eq!(
node_style_absolute(Path::new(r"\favicon"), Path::new(r"\\server\share\project")).as_deref(),
Some(Path::new(r"\\server\share\favicon"))
);
assert_eq!(node_style_absolute(Path::new("/favicon"), Path::new("relative")), None);
}
}