use std::path::Path;
use sugar_path::SugarPath;
use crate::{ContextGuard, Result, cacheable, with::AsConverter};
#[cacheable(crate=crate, hashable)]
pub struct PortablePath {
path: String,
transformed: bool,
}
impl PortablePath {
pub fn new(path: &Path, project_root: Option<&Path>) -> Self {
if path.is_absolute()
&& let Some(project_root) = project_root
{
return Self {
path: path.relative(project_root).to_slash_lossy().into_owned(),
transformed: true,
};
}
Self {
path: path.to_slash_lossy().into_owned(),
transformed: false,
}
}
pub fn into_path_string(self, project_root: Option<&Path>) -> String {
if self.transformed
&& let Some(project_root) = project_root
{
return self
.path
.absolutize_with(project_root)
.to_string_lossy()
.into_owned();
}
self.path
}
}
impl<T> AsConverter<T> for PortablePath
where
T: From<String> + AsRef<Path>,
{
fn serialize(data: &T, guard: &ContextGuard) -> Result<Self>
where
Self: Sized,
{
Ok(Self::new(data.as_ref(), guard.project_root()))
}
fn deserialize(self, guard: &ContextGuard) -> Result<T> {
Ok(T::from(self.into_path_string(guard.project_root())))
}
}