#[allow(unused_imports)]
use crate::prelude::*;
use bevy::ecs::error::BevyError;
use path_clean::PathClean;
use std::path::Path;
use std::path::PathBuf;
use std::str::FromStr;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(
Debug, Default, Clone, PartialEq, Eq, Hash, bevy::reflect::Reflect,
)]
pub struct WsPathBuf(
PathBuf,
);
impl std::fmt::Display for WsPathBuf {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0.to_string_lossy())
}
}
impl WsPathBuf {
pub fn new(path: impl AsRef<Path>) -> Self {
let path = path.as_ref();
#[cfg(target_os = "windows")]
let path = PathBuf::from(path.to_string_lossy().replace('\\', "/"));
let path = path.clean();
Self(path)
}
pub fn new_cwd_rel(path: impl AsRef<Path>) -> FsResult<Self> {
let path = path_ext::absolute(path)?;
let path = path_ext::strip_prefix(&path, &fs_ext::workspace_root())?;
Ok(Self::new(path))
}
pub fn take(self) -> PathBuf { self.0 }
pub fn join(&self, path: impl AsRef<Path>) -> Self {
let path = self.0.join(path).clean();
Self::new(path)
}
pub fn into_abs(&self) -> AbsPathBuf {
let path = fs_ext::workspace_root().join(self).clean();
AbsPathBuf::new(path)
.map_err(|err| {
format!("Failed to convert WsPathBuf to AbsPathBuf: {err}")
})
.unwrap()
}
}
impl std::ops::Deref for WsPathBuf {
type Target = PathBuf;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl std::ops::DerefMut for WsPathBuf {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
impl AsRef<Path> for WsPathBuf {
fn as_ref(&self) -> &Path { self.0.as_ref() }
}
impl FromStr for WsPathBuf {
type Err = BevyError;
fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(Self::new(s)) }
}
impl Into<WsPathBuf> for &str {
fn into(self) -> WsPathBuf { WsPathBuf::new(self) }
}
impl Into<WsPathBuf> for PathBuf {
fn into(self) -> WsPathBuf { WsPathBuf::new(self) }
}
#[cfg(test)]
mod test {
use crate::prelude::*;
use std::path::PathBuf;
#[test]
fn works() {
assert_eq!(
WsPathBuf::new("Cargo.toml").as_path(),
PathBuf::from("Cargo.toml").as_path()
);
assert_eq!(
WsPathBuf::new("foo/../Cargo.toml").as_path(),
PathBuf::from("Cargo.toml").as_path()
);
}
}