use std::path::PathBuf;
#[cfg(feature = "real")]
#[derive(Debug, Default, Clone)]
pub struct RealSys;
#[cfg(any(
all(feature = "real", target_os = "windows", feature = "winapi"),
all(feature = "real", unix, feature = "libc")
))]
pub use real::real_cache_dir_with_env;
#[cfg(any(
all(feature = "real", target_os = "windows", feature = "winapi"),
all(feature = "real", unix, feature = "libc")
))]
pub use real::real_home_dir_with_env;
#[cfg(feature = "memory")]
mod in_memory;
#[cfg(all(feature = "real", not(target_arch = "wasm32"),))]
mod real;
#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
mod wasm;
#[cfg(feature = "memory")]
pub use in_memory::InMemoryDirEntry;
#[cfg(feature = "memory")]
pub use in_memory::InMemoryFile;
#[cfg(feature = "memory")]
pub use in_memory::InMemoryMetadata;
#[cfg(feature = "memory")]
pub use in_memory::InMemorySys;
#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
pub use wasm::is_windows;
#[cfg(not(all(feature = "wasm", target_arch = "wasm32")))]
pub fn is_windows() -> bool {
cfg!(windows)
}
#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
pub type RealFsFile = wasm::WasmFile;
#[cfg(all(
feature = "real",
not(target_arch = "wasm32"),
not(feature = "wasm")
))]
pub type RealFsFile = real::RealFsFile;
#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
pub type RealFsMetadata = wasm::WasmMetadata;
#[cfg(all(
feature = "real",
not(target_arch = "wasm32"),
not(feature = "wasm")
))]
pub type RealFsMetadata = real::RealFsMetadata;
#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
pub type RealFsDirEntry = wasm::WasmFsDirEntry;
#[cfg(all(
feature = "real",
not(target_arch = "wasm32"),
not(feature = "wasm")
))]
pub type RealFsDirEntry = real::RealFsDirEntry;
#[cfg(feature = "real")]
pub fn wasm_string_to_path(path: String) -> PathBuf {
#[cfg(all(target_arch = "wasm32", feature = "wasm"))]
{
fn is_windows_absolute_path(path: &str) -> bool {
let mut chars = path.chars();
let Some(first_char) = chars.next() else {
return false;
};
if !first_char.is_alphabetic() {
return false;
}
let Some(second_char) = chars.next() else {
return false;
};
if second_char != ':' {
return false;
}
let third_char = chars.next();
third_char == Some('\\') || third_char == Some('/')
}
if wasm::is_windows() && is_windows_absolute_path(&path) {
PathBuf::from("/").join(path.replace("\\", "/"))
} else {
PathBuf::from(path)
}
}
#[cfg(not(target_arch = "wasm32"))]
{
PathBuf::from(path)
}
}
#[cfg(feature = "real")]
pub fn wasm_path_to_str(path: &std::path::Path) -> std::borrow::Cow<str> {
#[cfg(all(target_arch = "wasm32", feature = "wasm"))]
{
if wasm::is_windows() {
let path = path.to_string_lossy();
let path = path.strip_prefix('/').unwrap_or(&path);
std::borrow::Cow::Owned(path.replace("/", "\\"))
} else {
path.to_string_lossy()
}
}
#[cfg(any(not(target_arch = "wasm32"), not(feature = "wasm")))]
{
path.to_string_lossy()
}
}
#[cfg(any(not(windows), not(feature = "strip_unc")))]
#[inline]
#[allow(dead_code)]
pub(super) fn strip_unc_prefix(path: PathBuf) -> PathBuf {
path
}
#[cfg(all(windows, feature = "strip_unc"))]
pub(super) fn strip_unc_prefix(path: PathBuf) -> PathBuf {
use std::path::Component;
use std::path::Prefix;
let mut components = path.components();
match components.next() {
Some(Component::Prefix(prefix)) => {
match prefix.kind() {
Prefix::Verbatim(device) => {
let mut path = PathBuf::new();
path.push(format!(r"\\{}\", device.to_string_lossy()));
path.extend(components.filter(|c| !matches!(c, Component::RootDir)));
path
}
Prefix::VerbatimDisk(_) => {
let mut path = PathBuf::new();
path.push(prefix.as_os_str().to_string_lossy().replace(r"\\?\", ""));
path.extend(components);
path
}
Prefix::VerbatimUNC(hostname, share_name) => {
let mut path = PathBuf::new();
path.push(format!(
r"\\{}\{}\",
hostname.to_string_lossy(),
share_name.to_string_lossy()
));
path.extend(components.filter(|c| !matches!(c, Component::RootDir)));
path
}
_ => path,
}
}
_ => path,
}
}