use std::{
ffi::OsStr,
path::{Path, PathBuf},
};
use crate::utils::replace_placeholders;
use super::ProjectLayout;
#[derive(Clone, Debug)]
pub struct VariableScope {
workspace_dir: PathBuf,
package_dir: PathBuf,
tmp_dir: PathBuf,
}
impl VariableScope {
pub fn new(workspace_dir: PathBuf, package_dir: PathBuf, tmp_dir: PathBuf) -> Self {
Self {
workspace_dir,
package_dir,
tmp_dir,
}
}
pub fn for_package(layout: &ProjectLayout, package_dir: PathBuf) -> Self {
Self::new(
layout.workspace_dir().to_path_buf(),
package_dir,
std::env::temp_dir(),
)
}
pub fn workspace_dir(&self) -> &Path {
&self.workspace_dir
}
pub fn package_dir(&self) -> &Path {
&self.package_dir
}
pub fn tmp_dir(&self) -> &Path {
&self.tmp_dir
}
}
pub fn expand_variables(input: &str, scope: &VariableScope) -> anyhow::Result<String> {
let workspace_dir = scope.workspace_dir().display().to_string();
let package_dir = scope.package_dir().display().to_string();
let tmp_dir = scope.tmp_dir().display().to_string();
replace_placeholders(input, |placeholder| {
let value = match placeholder {
"workspace" | "workspaceFolder" => Some(workspace_dir.clone()),
"package" => Some(package_dir.clone()),
"tmpDir" => Some(tmp_dir.clone()),
p if p.starts_with("env:") => Some(std::env::var(&p[4..]).unwrap_or_default()),
_ => None,
};
Ok(value)
})
}
pub fn expand_os_value(value: &OsStr, scope: &VariableScope) -> String {
expand_variables(&value.to_string_lossy(), scope)
.unwrap_or_else(|_| value.to_string_lossy().into_owned())
}
pub fn expand_path_variables(path: &Path, scope: &VariableScope) -> anyhow::Result<PathBuf> {
Ok(PathBuf::from(expand_variables(
&path.to_string_lossy(),
scope,
)?))
}