use std::path::{Path, PathBuf};
use rho_sdk::{Workspace, WorkspacePathErrorKind};
pub(crate) fn canonical_root(root: &Path) -> Result<PathBuf, String> {
workspace(root).map(|workspace| workspace.root().to_path_buf())
}
pub(crate) fn contained_path(root: &Path, path: &Path) -> Result<PathBuf, String> {
let workspace = workspace(root)?;
workspace
.resolve_existing(path)
.map_err(|error| path_error(path, error))
}
pub(crate) fn resolve_in_root(root: &Path, tail: &str) -> Result<PathBuf, String> {
let workspace = workspace(root)?;
workspace
.resolve_for_write(root.join(tail))
.map(|resolved| resolved.path().to_path_buf())
.map_err(|error| path_error(&root.join(tail), error))
}
fn workspace(root: &Path) -> Result<Workspace, String> {
Workspace::new(root)
.map_err(|error| format!("cannot resolve plugin root `{}`: {error}", root.display()))
}
fn path_error(path: &Path, error: rho_sdk::WorkspacePathError) -> String {
if matches!(
error.kind(),
WorkspacePathErrorKind::OutsideGrantedRoots | WorkspacePathErrorKind::ParentTraversal
) {
format!("`{}` escapes the plugin root", path.display())
} else {
format!("cannot resolve `{}`: {error}", path.display())
}
}